ActivityManagerService.java revision 1dddc7fc790f14208516b4551ff12b2db8528864
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.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageStats;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1163
1164    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1165    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1166    static final int FIRST_COMPAT_MODE_MSG = 300;
1167    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1168
1169    AlertDialog mUidAlert;
1170    CompatModeDialog mCompatModeDialog;
1171    long mLastMemUsageReportTime = 0;
1172
1173    private LockToAppRequestDialog mLockToAppRequest;
1174
1175    /**
1176     * Flag whether the current user is a "monkey", i.e. whether
1177     * the UI is driven by a UI automation tool.
1178     */
1179    private boolean mUserIsMonkey;
1180
1181    /** Flag whether the device has a recents UI */
1182    final boolean mHasRecents;
1183
1184    final ServiceThread mHandlerThread;
1185    final MainHandler mHandler;
1186
1187    final class MainHandler extends Handler {
1188        public MainHandler(Looper looper) {
1189            super(looper, null, true);
1190        }
1191
1192        @Override
1193        public void handleMessage(Message msg) {
1194            switch (msg.what) {
1195            case SHOW_ERROR_MSG: {
1196                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1198                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1199                synchronized (ActivityManagerService.this) {
1200                    ProcessRecord proc = (ProcessRecord)data.get("app");
1201                    AppErrorResult res = (AppErrorResult) data.get("result");
1202                    if (proc != null && proc.crashDialog != null) {
1203                        Slog.e(TAG, "App already has crash dialog: " + proc);
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1210                            >= Process.FIRST_APPLICATION_UID
1211                            && proc.pid != MY_PID);
1212                    for (int userId : mCurrentProfileIds) {
1213                        isBackground &= (proc.userId != userId);
1214                    }
1215                    if (isBackground && !showBackground) {
1216                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1217                        if (res != null) {
1218                            res.set(0);
1219                        }
1220                        return;
1221                    }
1222                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1223                        Dialog d = new AppErrorDialog(mContext,
1224                                ActivityManagerService.this, res, proc);
1225                        d.show();
1226                        proc.crashDialog = d;
1227                    } else {
1228                        // The device is asleep, so just pretend that the user
1229                        // saw a crash dialog and hit "force quit".
1230                        if (res != null) {
1231                            res.set(0);
1232                        }
1233                    }
1234                }
1235
1236                ensureBootCompleted();
1237            } break;
1238            case SHOW_NOT_RESPONDING_MSG: {
1239                synchronized (ActivityManagerService.this) {
1240                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1241                    ProcessRecord proc = (ProcessRecord)data.get("app");
1242                    if (proc != null && proc.anrDialog != null) {
1243                        Slog.e(TAG, "App already has anr dialog: " + proc);
1244                        return;
1245                    }
1246
1247                    Intent intent = new Intent("android.intent.action.ANR");
1248                    if (!mProcessesReady) {
1249                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1250                                | Intent.FLAG_RECEIVER_FOREGROUND);
1251                    }
1252                    broadcastIntentLocked(null, null, intent,
1253                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1254                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1255
1256                    if (mShowDialogs) {
1257                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1258                                mContext, proc, (ActivityRecord)data.get("activity"),
1259                                msg.arg1 != 0);
1260                        d.show();
1261                        proc.anrDialog = d;
1262                    } else {
1263                        // Just kill the app if there is no dialog to be shown.
1264                        killAppAtUsersRequest(proc, null);
1265                    }
1266                }
1267
1268                ensureBootCompleted();
1269            } break;
1270            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1271                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1272                synchronized (ActivityManagerService.this) {
1273                    ProcessRecord proc = (ProcessRecord) data.get("app");
1274                    if (proc == null) {
1275                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1276                        break;
1277                    }
1278                    if (proc.crashDialog != null) {
1279                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1280                        return;
1281                    }
1282                    AppErrorResult res = (AppErrorResult) data.get("result");
1283                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1284                        Dialog d = new StrictModeViolationDialog(mContext,
1285                                ActivityManagerService.this, res, proc);
1286                        d.show();
1287                        proc.crashDialog = d;
1288                    } else {
1289                        // The device is asleep, so just pretend that the user
1290                        // saw a crash dialog and hit "force quit".
1291                        res.set(0);
1292                    }
1293                }
1294                ensureBootCompleted();
1295            } break;
1296            case SHOW_FACTORY_ERROR_MSG: {
1297                Dialog d = new FactoryErrorDialog(
1298                    mContext, msg.getData().getCharSequence("msg"));
1299                d.show();
1300                ensureBootCompleted();
1301            } break;
1302            case UPDATE_CONFIGURATION_MSG: {
1303                final ContentResolver resolver = mContext.getContentResolver();
1304                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1305            } break;
1306            case GC_BACKGROUND_PROCESSES_MSG: {
1307                synchronized (ActivityManagerService.this) {
1308                    performAppGcsIfAppropriateLocked();
1309                }
1310            } break;
1311            case WAIT_FOR_DEBUGGER_MSG: {
1312                synchronized (ActivityManagerService.this) {
1313                    ProcessRecord app = (ProcessRecord)msg.obj;
1314                    if (msg.arg1 != 0) {
1315                        if (!app.waitedForDebugger) {
1316                            Dialog d = new AppWaitingForDebuggerDialog(
1317                                    ActivityManagerService.this,
1318                                    mContext, app);
1319                            app.waitDialog = d;
1320                            app.waitedForDebugger = true;
1321                            d.show();
1322                        }
1323                    } else {
1324                        if (app.waitDialog != null) {
1325                            app.waitDialog.dismiss();
1326                            app.waitDialog = null;
1327                        }
1328                    }
1329                }
1330            } break;
1331            case SERVICE_TIMEOUT_MSG: {
1332                if (mDidDexOpt) {
1333                    mDidDexOpt = false;
1334                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1335                    nmsg.obj = msg.obj;
1336                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1337                    return;
1338                }
1339                mServices.serviceTimeout((ProcessRecord)msg.obj);
1340            } break;
1341            case UPDATE_TIME_ZONE: {
1342                synchronized (ActivityManagerService.this) {
1343                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1344                        ProcessRecord r = mLruProcesses.get(i);
1345                        if (r.thread != null) {
1346                            try {
1347                                r.thread.updateTimeZone();
1348                            } catch (RemoteException ex) {
1349                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1350                            }
1351                        }
1352                    }
1353                }
1354            } break;
1355            case CLEAR_DNS_CACHE_MSG: {
1356                synchronized (ActivityManagerService.this) {
1357                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1358                        ProcessRecord r = mLruProcesses.get(i);
1359                        if (r.thread != null) {
1360                            try {
1361                                r.thread.clearDnsCache();
1362                            } catch (RemoteException ex) {
1363                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1364                            }
1365                        }
1366                    }
1367                }
1368            } break;
1369            case UPDATE_HTTP_PROXY_MSG: {
1370                ProxyInfo proxy = (ProxyInfo)msg.obj;
1371                String host = "";
1372                String port = "";
1373                String exclList = "";
1374                Uri pacFileUrl = Uri.EMPTY;
1375                if (proxy != null) {
1376                    host = proxy.getHost();
1377                    port = Integer.toString(proxy.getPort());
1378                    exclList = proxy.getExclusionListAsString();
1379                    pacFileUrl = proxy.getPacFileUrl();
1380                }
1381                synchronized (ActivityManagerService.this) {
1382                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1383                        ProcessRecord r = mLruProcesses.get(i);
1384                        if (r.thread != null) {
1385                            try {
1386                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1387                            } catch (RemoteException ex) {
1388                                Slog.w(TAG, "Failed to update http proxy for: " +
1389                                        r.info.processName);
1390                            }
1391                        }
1392                    }
1393                }
1394            } break;
1395            case SHOW_UID_ERROR_MSG: {
1396                String title = "System UIDs Inconsistent";
1397                String text = "UIDs on the system are inconsistent, you need to wipe your"
1398                        + " data partition or your device will be unstable.";
1399                Log.e(TAG, title + ": " + text);
1400                if (mShowDialogs) {
1401                    // XXX This is a temporary dialog, no need to localize.
1402                    AlertDialog d = new BaseErrorDialog(mContext);
1403                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1404                    d.setCancelable(false);
1405                    d.setTitle(title);
1406                    d.setMessage(text);
1407                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1408                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1409                    mUidAlert = d;
1410                    d.show();
1411                }
1412            } break;
1413            case IM_FEELING_LUCKY_MSG: {
1414                if (mUidAlert != null) {
1415                    mUidAlert.dismiss();
1416                    mUidAlert = null;
1417                }
1418            } break;
1419            case PROC_START_TIMEOUT_MSG: {
1420                if (mDidDexOpt) {
1421                    mDidDexOpt = false;
1422                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1423                    nmsg.obj = msg.obj;
1424                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1425                    return;
1426                }
1427                ProcessRecord app = (ProcessRecord)msg.obj;
1428                synchronized (ActivityManagerService.this) {
1429                    processStartTimedOutLocked(app);
1430                }
1431            } break;
1432            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1435                }
1436            } break;
1437            case KILL_APPLICATION_MSG: {
1438                synchronized (ActivityManagerService.this) {
1439                    int appid = msg.arg1;
1440                    boolean restart = (msg.arg2 == 1);
1441                    Bundle bundle = (Bundle)msg.obj;
1442                    String pkg = bundle.getString("pkg");
1443                    String reason = bundle.getString("reason");
1444                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1445                            false, UserHandle.USER_ALL, reason);
1446                }
1447            } break;
1448            case FINALIZE_PENDING_INTENT_MSG: {
1449                ((PendingIntentRecord)msg.obj).completeFinalize();
1450            } break;
1451            case POST_HEAVY_NOTIFICATION_MSG: {
1452                INotificationManager inm = NotificationManager.getService();
1453                if (inm == null) {
1454                    return;
1455                }
1456
1457                ActivityRecord root = (ActivityRecord)msg.obj;
1458                ProcessRecord process = root.app;
1459                if (process == null) {
1460                    return;
1461                }
1462
1463                try {
1464                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1465                    String text = mContext.getString(R.string.heavy_weight_notification,
1466                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1467                    Notification notification = new Notification();
1468                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1469                    notification.when = 0;
1470                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1471                    notification.tickerText = text;
1472                    notification.defaults = 0; // please be quiet
1473                    notification.sound = null;
1474                    notification.vibrate = null;
1475                    notification.setLatestEventInfo(context, text,
1476                            mContext.getText(R.string.heavy_weight_notification_detail),
1477                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1478                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1479                                    new UserHandle(root.userId)));
1480
1481                    try {
1482                        int[] outId = new int[1];
1483                        inm.enqueueNotificationWithTag("android", "android", null,
1484                                R.string.heavy_weight_notification,
1485                                notification, outId, root.userId);
1486                    } catch (RuntimeException e) {
1487                        Slog.w(ActivityManagerService.TAG,
1488                                "Error showing notification for heavy-weight app", e);
1489                    } catch (RemoteException e) {
1490                    }
1491                } catch (NameNotFoundException e) {
1492                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1493                }
1494            } break;
1495            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1496                INotificationManager inm = NotificationManager.getService();
1497                if (inm == null) {
1498                    return;
1499                }
1500                try {
1501                    inm.cancelNotificationWithTag("android", null,
1502                            R.string.heavy_weight_notification,  msg.arg1);
1503                } catch (RuntimeException e) {
1504                    Slog.w(ActivityManagerService.TAG,
1505                            "Error canceling notification for service", e);
1506                } catch (RemoteException e) {
1507                }
1508            } break;
1509            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1510                synchronized (ActivityManagerService.this) {
1511                    checkExcessivePowerUsageLocked(true);
1512                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1513                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1514                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1515                }
1516            } break;
1517            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1518                synchronized (ActivityManagerService.this) {
1519                    ActivityRecord ar = (ActivityRecord)msg.obj;
1520                    if (mCompatModeDialog != null) {
1521                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1522                                ar.info.applicationInfo.packageName)) {
1523                            return;
1524                        }
1525                        mCompatModeDialog.dismiss();
1526                        mCompatModeDialog = null;
1527                    }
1528                    if (ar != null && false) {
1529                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1530                                ar.packageName)) {
1531                            int mode = mCompatModePackages.computeCompatModeLocked(
1532                                    ar.info.applicationInfo);
1533                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1534                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1535                                mCompatModeDialog = new CompatModeDialog(
1536                                        ActivityManagerService.this, mContext,
1537                                        ar.info.applicationInfo);
1538                                mCompatModeDialog.show();
1539                            }
1540                        }
1541                    }
1542                }
1543                break;
1544            }
1545            case DISPATCH_PROCESSES_CHANGED: {
1546                dispatchProcessesChanged();
1547                break;
1548            }
1549            case DISPATCH_PROCESS_DIED: {
1550                final int pid = msg.arg1;
1551                final int uid = msg.arg2;
1552                dispatchProcessDied(pid, uid);
1553                break;
1554            }
1555            case REPORT_MEM_USAGE_MSG: {
1556                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1557                Thread thread = new Thread() {
1558                    @Override public void run() {
1559                        final SparseArray<ProcessMemInfo> infoMap
1560                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1561                        for (int i=0, N=memInfos.size(); i<N; i++) {
1562                            ProcessMemInfo mi = memInfos.get(i);
1563                            infoMap.put(mi.pid, mi);
1564                        }
1565                        updateCpuStatsNow();
1566                        synchronized (mProcessCpuThread) {
1567                            final int N = mProcessCpuTracker.countStats();
1568                            for (int i=0; i<N; i++) {
1569                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1570                                if (st.vsize > 0) {
1571                                    long pss = Debug.getPss(st.pid, null);
1572                                    if (pss > 0) {
1573                                        if (infoMap.indexOfKey(st.pid) < 0) {
1574                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1575                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1576                                            mi.pss = pss;
1577                                            memInfos.add(mi);
1578                                        }
1579                                    }
1580                                }
1581                            }
1582                        }
1583
1584                        long totalPss = 0;
1585                        for (int i=0, N=memInfos.size(); i<N; i++) {
1586                            ProcessMemInfo mi = memInfos.get(i);
1587                            if (mi.pss == 0) {
1588                                mi.pss = Debug.getPss(mi.pid, null);
1589                            }
1590                            totalPss += mi.pss;
1591                        }
1592                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1593                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1594                                if (lhs.oomAdj != rhs.oomAdj) {
1595                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1596                                }
1597                                if (lhs.pss != rhs.pss) {
1598                                    return lhs.pss < rhs.pss ? 1 : -1;
1599                                }
1600                                return 0;
1601                            }
1602                        });
1603
1604                        StringBuilder tag = new StringBuilder(128);
1605                        StringBuilder stack = new StringBuilder(128);
1606                        tag.append("Low on memory -- ");
1607                        appendMemBucket(tag, totalPss, "total", false);
1608                        appendMemBucket(stack, totalPss, "total", true);
1609
1610                        StringBuilder logBuilder = new StringBuilder(1024);
1611                        logBuilder.append("Low on memory:\n");
1612
1613                        boolean firstLine = true;
1614                        int lastOomAdj = Integer.MIN_VALUE;
1615                        for (int i=0, N=memInfos.size(); i<N; i++) {
1616                            ProcessMemInfo mi = memInfos.get(i);
1617
1618                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1619                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1620                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1621                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1622                                if (lastOomAdj != mi.oomAdj) {
1623                                    lastOomAdj = mi.oomAdj;
1624                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1625                                        tag.append(" / ");
1626                                    }
1627                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1628                                        if (firstLine) {
1629                                            stack.append(":");
1630                                            firstLine = false;
1631                                        }
1632                                        stack.append("\n\t at ");
1633                                    } else {
1634                                        stack.append("$");
1635                                    }
1636                                } else {
1637                                    tag.append(" ");
1638                                    stack.append("$");
1639                                }
1640                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1641                                    appendMemBucket(tag, mi.pss, mi.name, false);
1642                                }
1643                                appendMemBucket(stack, mi.pss, mi.name, true);
1644                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1645                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1646                                    stack.append("(");
1647                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1648                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1649                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1650                                            stack.append(":");
1651                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1652                                        }
1653                                    }
1654                                    stack.append(")");
1655                                }
1656                            }
1657
1658                            logBuilder.append("  ");
1659                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1660                            logBuilder.append(' ');
1661                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1662                            logBuilder.append(' ');
1663                            ProcessList.appendRamKb(logBuilder, mi.pss);
1664                            logBuilder.append(" kB: ");
1665                            logBuilder.append(mi.name);
1666                            logBuilder.append(" (");
1667                            logBuilder.append(mi.pid);
1668                            logBuilder.append(") ");
1669                            logBuilder.append(mi.adjType);
1670                            logBuilder.append('\n');
1671                            if (mi.adjReason != null) {
1672                                logBuilder.append("                      ");
1673                                logBuilder.append(mi.adjReason);
1674                                logBuilder.append('\n');
1675                            }
1676                        }
1677
1678                        logBuilder.append("           ");
1679                        ProcessList.appendRamKb(logBuilder, totalPss);
1680                        logBuilder.append(" kB: TOTAL\n");
1681
1682                        long[] infos = new long[Debug.MEMINFO_COUNT];
1683                        Debug.getMemInfo(infos);
1684                        logBuilder.append("  MemInfo: ");
1685                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1686                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1687                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1688                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1689                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1690                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1691                            logBuilder.append("  ZRAM: ");
1692                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1693                            logBuilder.append(" kB RAM, ");
1694                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1695                            logBuilder.append(" kB swap total, ");
1696                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1697                            logBuilder.append(" kB swap free\n");
1698                        }
1699                        Slog.i(TAG, logBuilder.toString());
1700
1701                        StringBuilder dropBuilder = new StringBuilder(1024);
1702                        /*
1703                        StringWriter oomSw = new StringWriter();
1704                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1705                        StringWriter catSw = new StringWriter();
1706                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1707                        String[] emptyArgs = new String[] { };
1708                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1709                        oomPw.flush();
1710                        String oomString = oomSw.toString();
1711                        */
1712                        dropBuilder.append(stack);
1713                        dropBuilder.append('\n');
1714                        dropBuilder.append('\n');
1715                        dropBuilder.append(logBuilder);
1716                        dropBuilder.append('\n');
1717                        /*
1718                        dropBuilder.append(oomString);
1719                        dropBuilder.append('\n');
1720                        */
1721                        StringWriter catSw = new StringWriter();
1722                        synchronized (ActivityManagerService.this) {
1723                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1724                            String[] emptyArgs = new String[] { };
1725                            catPw.println();
1726                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1727                            catPw.println();
1728                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1729                                    false, false, null);
1730                            catPw.println();
1731                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1732                            catPw.flush();
1733                        }
1734                        dropBuilder.append(catSw.toString());
1735                        addErrorToDropBox("lowmem", null, "system_server", null,
1736                                null, tag.toString(), dropBuilder.toString(), null, null);
1737                        //Slog.i(TAG, "Sent to dropbox:");
1738                        //Slog.i(TAG, dropBuilder.toString());
1739                        synchronized (ActivityManagerService.this) {
1740                            long now = SystemClock.uptimeMillis();
1741                            if (mLastMemUsageReportTime < now) {
1742                                mLastMemUsageReportTime = now;
1743                            }
1744                        }
1745                    }
1746                };
1747                thread.start();
1748                break;
1749            }
1750            case REPORT_USER_SWITCH_MSG: {
1751                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1752                break;
1753            }
1754            case CONTINUE_USER_SWITCH_MSG: {
1755                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1756                break;
1757            }
1758            case USER_SWITCH_TIMEOUT_MSG: {
1759                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1760                break;
1761            }
1762            case IMMERSIVE_MODE_LOCK_MSG: {
1763                final boolean nextState = (msg.arg1 != 0);
1764                if (mUpdateLock.isHeld() != nextState) {
1765                    if (DEBUG_IMMERSIVE) {
1766                        final ActivityRecord r = (ActivityRecord) msg.obj;
1767                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1768                    }
1769                    if (nextState) {
1770                        mUpdateLock.acquire();
1771                    } else {
1772                        mUpdateLock.release();
1773                    }
1774                }
1775                break;
1776            }
1777            case PERSIST_URI_GRANTS_MSG: {
1778                writeGrantedUriPermissions();
1779                break;
1780            }
1781            case REQUEST_ALL_PSS_MSG: {
1782                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1783                break;
1784            }
1785            case START_PROFILES_MSG: {
1786                synchronized (ActivityManagerService.this) {
1787                    startProfilesLocked();
1788                }
1789                break;
1790            }
1791            case UPDATE_TIME: {
1792                synchronized (ActivityManagerService.this) {
1793                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1794                        ProcessRecord r = mLruProcesses.get(i);
1795                        if (r.thread != null) {
1796                            try {
1797                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1798                            } catch (RemoteException ex) {
1799                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1800                            }
1801                        }
1802                    }
1803                }
1804                break;
1805            }
1806            case SYSTEM_USER_START_MSG: {
1807                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1808                        Integer.toString(msg.arg1), msg.arg1);
1809                mSystemServiceManager.startUser(msg.arg1);
1810                break;
1811            }
1812            case SYSTEM_USER_CURRENT_MSG: {
1813                mBatteryStatsService.noteEvent(
1814                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1815                        Integer.toString(msg.arg2), msg.arg2);
1816                mBatteryStatsService.noteEvent(
1817                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1818                        Integer.toString(msg.arg1), msg.arg1);
1819                mSystemServiceManager.switchUser(msg.arg1);
1820                break;
1821            }
1822            case ENTER_ANIMATION_COMPLETE_MSG: {
1823                synchronized (ActivityManagerService.this) {
1824                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1825                    if (r != null && r.app != null && r.app.thread != null) {
1826                        try {
1827                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1828                        } catch (RemoteException e) {
1829                        }
1830                    }
1831                }
1832                break;
1833            }
1834            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1835                enableScreenAfterBoot();
1836                break;
1837            }
1838            }
1839        }
1840    };
1841
1842    static final int COLLECT_PSS_BG_MSG = 1;
1843
1844    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1845        @Override
1846        public void handleMessage(Message msg) {
1847            switch (msg.what) {
1848            case COLLECT_PSS_BG_MSG: {
1849                long start = SystemClock.uptimeMillis();
1850                MemInfoReader memInfo = null;
1851                synchronized (ActivityManagerService.this) {
1852                    if (mFullPssPending) {
1853                        mFullPssPending = false;
1854                        memInfo = new MemInfoReader();
1855                    }
1856                }
1857                if (memInfo != null) {
1858                    updateCpuStatsNow();
1859                    long nativeTotalPss = 0;
1860                    synchronized (mProcessCpuThread) {
1861                        final int N = mProcessCpuTracker.countStats();
1862                        for (int j=0; j<N; j++) {
1863                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1864                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1865                                // This is definitely an application process; skip it.
1866                                continue;
1867                            }
1868                            synchronized (mPidsSelfLocked) {
1869                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1870                                    // This is one of our own processes; skip it.
1871                                    continue;
1872                                }
1873                            }
1874                            nativeTotalPss += Debug.getPss(st.pid, null);
1875                        }
1876                    }
1877                    memInfo.readMemInfo();
1878                    synchronized (this) {
1879                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1880                                + (SystemClock.uptimeMillis()-start) + "ms");
1881                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1882                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1883                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1884                                        +memInfo.getSlabSizeKb(),
1885                                nativeTotalPss);
1886                    }
1887                }
1888
1889                int i=0, num=0;
1890                long[] tmp = new long[1];
1891                do {
1892                    ProcessRecord proc;
1893                    int procState;
1894                    int pid;
1895                    synchronized (ActivityManagerService.this) {
1896                        if (i >= mPendingPssProcesses.size()) {
1897                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1898                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1899                            mPendingPssProcesses.clear();
1900                            return;
1901                        }
1902                        proc = mPendingPssProcesses.get(i);
1903                        procState = proc.pssProcState;
1904                        if (proc.thread != null && procState == proc.setProcState) {
1905                            pid = proc.pid;
1906                        } else {
1907                            proc = null;
1908                            pid = 0;
1909                        }
1910                        i++;
1911                    }
1912                    if (proc != null) {
1913                        long pss = Debug.getPss(pid, tmp);
1914                        synchronized (ActivityManagerService.this) {
1915                            if (proc.thread != null && proc.setProcState == procState
1916                                    && proc.pid == pid) {
1917                                num++;
1918                                proc.lastPssTime = SystemClock.uptimeMillis();
1919                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1920                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1921                                        + ": " + pss + " lastPss=" + proc.lastPss
1922                                        + " state=" + ProcessList.makeProcStateString(procState));
1923                                if (proc.initialIdlePss == 0) {
1924                                    proc.initialIdlePss = pss;
1925                                }
1926                                proc.lastPss = pss;
1927                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1928                                    proc.lastCachedPss = pss;
1929                                }
1930                            }
1931                        }
1932                    }
1933                } while (true);
1934            }
1935            }
1936        }
1937    };
1938
1939    /**
1940     * Monitor for package changes and update our internal state.
1941     */
1942    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1943        @Override
1944        public void onPackageRemoved(String packageName, int uid) {
1945            // Remove all tasks with activities in the specified package from the list of recent tasks
1946            synchronized (ActivityManagerService.this) {
1947                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1948                    TaskRecord tr = mRecentTasks.get(i);
1949                    ComponentName cn = tr.intent.getComponent();
1950                    if (cn != null && cn.getPackageName().equals(packageName)) {
1951                        // If the package name matches, remove the task and kill the process
1952                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1953                    }
1954                }
1955            }
1956        }
1957
1958        @Override
1959        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1960            onPackageModified(packageName);
1961            return true;
1962        }
1963
1964        @Override
1965        public void onPackageModified(String packageName) {
1966            final PackageManager pm = mContext.getPackageManager();
1967            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1968                    new ArrayList<Pair<Intent, Integer>>();
1969            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1970            // Copy the list of recent tasks so that we don't hold onto the lock on
1971            // ActivityManagerService for long periods while checking if components exist.
1972            synchronized (ActivityManagerService.this) {
1973                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1974                    TaskRecord tr = mRecentTasks.get(i);
1975                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1976                }
1977            }
1978            // Check the recent tasks and filter out all tasks with components that no longer exist.
1979            Intent tmpI = new Intent();
1980            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1981                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1982                ComponentName cn = p.first.getComponent();
1983                if (cn != null && cn.getPackageName().equals(packageName)) {
1984                    try {
1985                        // Add the task to the list to remove if the component no longer exists
1986                        tmpI.setComponent(cn);
1987                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1988                            tasksToRemove.add(p.second);
1989                        }
1990                    } catch (Exception e) {}
1991                }
1992            }
1993            // Prune all the tasks with removed components from the list of recent tasks
1994            synchronized (ActivityManagerService.this) {
1995                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1996                    // Remove the task but don't kill the process (since other components in that
1997                    // package may still be running and in the background)
1998                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1999                }
2000            }
2001        }
2002
2003        @Override
2004        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2005            // Force stop the specified packages
2006            if (packages != null) {
2007                for (String pkg : packages) {
2008                    synchronized (ActivityManagerService.this) {
2009                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2010                                "finished booting")) {
2011                            return true;
2012                        }
2013                    }
2014                }
2015            }
2016            return false;
2017        }
2018    };
2019
2020    public void setSystemProcess() {
2021        try {
2022            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2023            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2024            ServiceManager.addService("meminfo", new MemBinder(this));
2025            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2026            ServiceManager.addService("dbinfo", new DbBinder(this));
2027            if (MONITOR_CPU_USAGE) {
2028                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2029            }
2030            ServiceManager.addService("permission", new PermissionController(this));
2031
2032            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2033                    "android", STOCK_PM_FLAGS);
2034            mSystemThread.installSystemApplicationInfo(info);
2035
2036            synchronized (this) {
2037                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2038                app.persistent = true;
2039                app.pid = MY_PID;
2040                app.maxAdj = ProcessList.SYSTEM_ADJ;
2041                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2042                mProcessNames.put(app.processName, app.uid, app);
2043                synchronized (mPidsSelfLocked) {
2044                    mPidsSelfLocked.put(app.pid, app);
2045                }
2046                updateLruProcessLocked(app, false, null);
2047                updateOomAdjLocked();
2048            }
2049        } catch (PackageManager.NameNotFoundException e) {
2050            throw new RuntimeException(
2051                    "Unable to find android system package", e);
2052        }
2053    }
2054
2055    public void setWindowManager(WindowManagerService wm) {
2056        mWindowManager = wm;
2057        mStackSupervisor.setWindowManager(wm);
2058    }
2059
2060    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2061        mUsageStatsService = usageStatsManager;
2062    }
2063
2064    public void startObservingNativeCrashes() {
2065        final NativeCrashListener ncl = new NativeCrashListener(this);
2066        ncl.start();
2067    }
2068
2069    public IAppOpsService getAppOpsService() {
2070        return mAppOpsService;
2071    }
2072
2073    static class MemBinder extends Binder {
2074        ActivityManagerService mActivityManagerService;
2075        MemBinder(ActivityManagerService activityManagerService) {
2076            mActivityManagerService = activityManagerService;
2077        }
2078
2079        @Override
2080        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2081            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2082                    != PackageManager.PERMISSION_GRANTED) {
2083                pw.println("Permission Denial: can't dump meminfo from from pid="
2084                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2085                        + " without permission " + android.Manifest.permission.DUMP);
2086                return;
2087            }
2088
2089            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2090        }
2091    }
2092
2093    static class GraphicsBinder extends Binder {
2094        ActivityManagerService mActivityManagerService;
2095        GraphicsBinder(ActivityManagerService activityManagerService) {
2096            mActivityManagerService = activityManagerService;
2097        }
2098
2099        @Override
2100        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2101            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2102                    != PackageManager.PERMISSION_GRANTED) {
2103                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2104                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2105                        + " without permission " + android.Manifest.permission.DUMP);
2106                return;
2107            }
2108
2109            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2110        }
2111    }
2112
2113    static class DbBinder extends Binder {
2114        ActivityManagerService mActivityManagerService;
2115        DbBinder(ActivityManagerService activityManagerService) {
2116            mActivityManagerService = activityManagerService;
2117        }
2118
2119        @Override
2120        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2121            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2122                    != PackageManager.PERMISSION_GRANTED) {
2123                pw.println("Permission Denial: can't dump dbinfo from from pid="
2124                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2125                        + " without permission " + android.Manifest.permission.DUMP);
2126                return;
2127            }
2128
2129            mActivityManagerService.dumpDbInfo(fd, pw, args);
2130        }
2131    }
2132
2133    static class CpuBinder extends Binder {
2134        ActivityManagerService mActivityManagerService;
2135        CpuBinder(ActivityManagerService activityManagerService) {
2136            mActivityManagerService = activityManagerService;
2137        }
2138
2139        @Override
2140        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2141            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2142                    != PackageManager.PERMISSION_GRANTED) {
2143                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2144                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2145                        + " without permission " + android.Manifest.permission.DUMP);
2146                return;
2147            }
2148
2149            synchronized (mActivityManagerService.mProcessCpuThread) {
2150                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2151                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2152                        SystemClock.uptimeMillis()));
2153            }
2154        }
2155    }
2156
2157    public static final class Lifecycle extends SystemService {
2158        private final ActivityManagerService mService;
2159
2160        public Lifecycle(Context context) {
2161            super(context);
2162            mService = new ActivityManagerService(context);
2163        }
2164
2165        @Override
2166        public void onStart() {
2167            mService.start();
2168        }
2169
2170        public ActivityManagerService getService() {
2171            return mService;
2172        }
2173    }
2174
2175    // Note: This method is invoked on the main thread but may need to attach various
2176    // handlers to other threads.  So take care to be explicit about the looper.
2177    public ActivityManagerService(Context systemContext) {
2178        mContext = systemContext;
2179        mFactoryTest = FactoryTest.getMode();
2180        mSystemThread = ActivityThread.currentActivityThread();
2181
2182        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2183
2184        mHandlerThread = new ServiceThread(TAG,
2185                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2186        mHandlerThread.start();
2187        mHandler = new MainHandler(mHandlerThread.getLooper());
2188
2189        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2190                "foreground", BROADCAST_FG_TIMEOUT, false);
2191        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2192                "background", BROADCAST_BG_TIMEOUT, true);
2193        mBroadcastQueues[0] = mFgBroadcastQueue;
2194        mBroadcastQueues[1] = mBgBroadcastQueue;
2195
2196        mServices = new ActiveServices(this);
2197        mProviderMap = new ProviderMap(this);
2198
2199        // TODO: Move creation of battery stats service outside of activity manager service.
2200        File dataDir = Environment.getDataDirectory();
2201        File systemDir = new File(dataDir, "system");
2202        systemDir.mkdirs();
2203        mBatteryStatsService = new BatteryStatsService(new File(
2204                systemDir, "batterystats.bin").toString(), mHandler);
2205        mBatteryStatsService.getActiveStatistics().readLocked();
2206        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2207        mOnBattery = DEBUG_POWER ? true
2208                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2209        mBatteryStatsService.getActiveStatistics().setCallback(this);
2210
2211        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2212
2213        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2214
2215        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2216
2217        // User 0 is the first and only user that runs at boot.
2218        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2219        mUserLru.add(Integer.valueOf(0));
2220        updateStartedUserArrayLocked();
2221
2222        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2223            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2224
2225        mConfiguration.setToDefaults();
2226        mConfiguration.setLocale(Locale.getDefault());
2227
2228        mConfigurationSeq = mConfiguration.seq = 1;
2229        mProcessCpuTracker.init();
2230
2231        mHasRecents = mContext.getResources().getBoolean(
2232                com.android.internal.R.bool.config_hasRecents);
2233
2234        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2235        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2236        mStackSupervisor = new ActivityStackSupervisor(this);
2237        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2238
2239        mProcessCpuThread = new Thread("CpuTracker") {
2240            @Override
2241            public void run() {
2242                while (true) {
2243                    try {
2244                        try {
2245                            synchronized(this) {
2246                                final long now = SystemClock.uptimeMillis();
2247                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2248                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2249                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2250                                //        + ", write delay=" + nextWriteDelay);
2251                                if (nextWriteDelay < nextCpuDelay) {
2252                                    nextCpuDelay = nextWriteDelay;
2253                                }
2254                                if (nextCpuDelay > 0) {
2255                                    mProcessCpuMutexFree.set(true);
2256                                    this.wait(nextCpuDelay);
2257                                }
2258                            }
2259                        } catch (InterruptedException e) {
2260                        }
2261                        updateCpuStatsNow();
2262                    } catch (Exception e) {
2263                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2264                    }
2265                }
2266            }
2267        };
2268
2269        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2270
2271        Watchdog.getInstance().addMonitor(this);
2272        Watchdog.getInstance().addThread(mHandler);
2273    }
2274
2275    public void setSystemServiceManager(SystemServiceManager mgr) {
2276        mSystemServiceManager = mgr;
2277    }
2278
2279    private void start() {
2280        Process.removeAllProcessGroups();
2281        mProcessCpuThread.start();
2282
2283        mBatteryStatsService.publish(mContext);
2284        mAppOpsService.publish(mContext);
2285        Slog.d("AppOps", "AppOpsService published");
2286        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2287    }
2288
2289    public void initPowerManagement() {
2290        mStackSupervisor.initPowerManagement();
2291        mBatteryStatsService.initPowerManagement();
2292    }
2293
2294    @Override
2295    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2296            throws RemoteException {
2297        if (code == SYSPROPS_TRANSACTION) {
2298            // We need to tell all apps about the system property change.
2299            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2300            synchronized(this) {
2301                final int NP = mProcessNames.getMap().size();
2302                for (int ip=0; ip<NP; ip++) {
2303                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2304                    final int NA = apps.size();
2305                    for (int ia=0; ia<NA; ia++) {
2306                        ProcessRecord app = apps.valueAt(ia);
2307                        if (app.thread != null) {
2308                            procs.add(app.thread.asBinder());
2309                        }
2310                    }
2311                }
2312            }
2313
2314            int N = procs.size();
2315            for (int i=0; i<N; i++) {
2316                Parcel data2 = Parcel.obtain();
2317                try {
2318                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2319                } catch (RemoteException e) {
2320                }
2321                data2.recycle();
2322            }
2323        }
2324        try {
2325            return super.onTransact(code, data, reply, flags);
2326        } catch (RuntimeException e) {
2327            // The activity manager only throws security exceptions, so let's
2328            // log all others.
2329            if (!(e instanceof SecurityException)) {
2330                Slog.wtf(TAG, "Activity Manager Crash", e);
2331            }
2332            throw e;
2333        }
2334    }
2335
2336    void updateCpuStats() {
2337        final long now = SystemClock.uptimeMillis();
2338        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2339            return;
2340        }
2341        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2342            synchronized (mProcessCpuThread) {
2343                mProcessCpuThread.notify();
2344            }
2345        }
2346    }
2347
2348    void updateCpuStatsNow() {
2349        synchronized (mProcessCpuThread) {
2350            mProcessCpuMutexFree.set(false);
2351            final long now = SystemClock.uptimeMillis();
2352            boolean haveNewCpuStats = false;
2353
2354            if (MONITOR_CPU_USAGE &&
2355                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2356                mLastCpuTime.set(now);
2357                haveNewCpuStats = true;
2358                mProcessCpuTracker.update();
2359                //Slog.i(TAG, mProcessCpu.printCurrentState());
2360                //Slog.i(TAG, "Total CPU usage: "
2361                //        + mProcessCpu.getTotalCpuPercent() + "%");
2362
2363                // Slog the cpu usage if the property is set.
2364                if ("true".equals(SystemProperties.get("events.cpu"))) {
2365                    int user = mProcessCpuTracker.getLastUserTime();
2366                    int system = mProcessCpuTracker.getLastSystemTime();
2367                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2368                    int irq = mProcessCpuTracker.getLastIrqTime();
2369                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2370                    int idle = mProcessCpuTracker.getLastIdleTime();
2371
2372                    int total = user + system + iowait + irq + softIrq + idle;
2373                    if (total == 0) total = 1;
2374
2375                    EventLog.writeEvent(EventLogTags.CPU,
2376                            ((user+system+iowait+irq+softIrq) * 100) / total,
2377                            (user * 100) / total,
2378                            (system * 100) / total,
2379                            (iowait * 100) / total,
2380                            (irq * 100) / total,
2381                            (softIrq * 100) / total);
2382                }
2383            }
2384
2385            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2386            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2387            synchronized(bstats) {
2388                synchronized(mPidsSelfLocked) {
2389                    if (haveNewCpuStats) {
2390                        if (mOnBattery) {
2391                            int perc = bstats.startAddingCpuLocked();
2392                            int totalUTime = 0;
2393                            int totalSTime = 0;
2394                            final int N = mProcessCpuTracker.countStats();
2395                            for (int i=0; i<N; i++) {
2396                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2397                                if (!st.working) {
2398                                    continue;
2399                                }
2400                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2401                                int otherUTime = (st.rel_utime*perc)/100;
2402                                int otherSTime = (st.rel_stime*perc)/100;
2403                                totalUTime += otherUTime;
2404                                totalSTime += otherSTime;
2405                                if (pr != null) {
2406                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2407                                    if (ps == null || !ps.isActive()) {
2408                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2409                                                pr.info.uid, pr.processName);
2410                                    }
2411                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2412                                            st.rel_stime-otherSTime);
2413                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2414                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2415                                } else {
2416                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2417                                    if (ps == null || !ps.isActive()) {
2418                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2419                                                bstats.mapUid(st.uid), st.name);
2420                                    }
2421                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2422                                            st.rel_stime-otherSTime);
2423                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2424                                }
2425                            }
2426                            bstats.finishAddingCpuLocked(perc, totalUTime,
2427                                    totalSTime, cpuSpeedTimes);
2428                        }
2429                    }
2430                }
2431
2432                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2433                    mLastWriteTime = now;
2434                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2435                }
2436            }
2437        }
2438    }
2439
2440    @Override
2441    public void batteryNeedsCpuUpdate() {
2442        updateCpuStatsNow();
2443    }
2444
2445    @Override
2446    public void batteryPowerChanged(boolean onBattery) {
2447        // When plugging in, update the CPU stats first before changing
2448        // the plug state.
2449        updateCpuStatsNow();
2450        synchronized (this) {
2451            synchronized(mPidsSelfLocked) {
2452                mOnBattery = DEBUG_POWER ? true : onBattery;
2453            }
2454        }
2455    }
2456
2457    /**
2458     * Initialize the application bind args. These are passed to each
2459     * process when the bindApplication() IPC is sent to the process. They're
2460     * lazily setup to make sure the services are running when they're asked for.
2461     */
2462    private HashMap<String, IBinder> getCommonServicesLocked() {
2463        if (mAppBindArgs == null) {
2464            mAppBindArgs = new HashMap<String, IBinder>();
2465
2466            // Setup the application init args
2467            mAppBindArgs.put("package", ServiceManager.getService("package"));
2468            mAppBindArgs.put("window", ServiceManager.getService("window"));
2469            mAppBindArgs.put(Context.ALARM_SERVICE,
2470                    ServiceManager.getService(Context.ALARM_SERVICE));
2471        }
2472        return mAppBindArgs;
2473    }
2474
2475    final void setFocusedActivityLocked(ActivityRecord r) {
2476        if (mFocusedActivity != r) {
2477            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2478            mFocusedActivity = r;
2479            if (r.task != null && r.task.voiceInteractor != null) {
2480                startRunningVoiceLocked();
2481            } else {
2482                finishRunningVoiceLocked();
2483            }
2484            mStackSupervisor.setFocusedStack(r);
2485            if (r != null) {
2486                mWindowManager.setFocusedApp(r.appToken, true);
2487            }
2488            applyUpdateLockStateLocked(r);
2489        }
2490    }
2491
2492    final void clearFocusedActivity(ActivityRecord r) {
2493        if (mFocusedActivity == r) {
2494            mFocusedActivity = null;
2495        }
2496    }
2497
2498    @Override
2499    public void setFocusedStack(int stackId) {
2500        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2501        synchronized (ActivityManagerService.this) {
2502            ActivityStack stack = mStackSupervisor.getStack(stackId);
2503            if (stack != null) {
2504                ActivityRecord r = stack.topRunningActivityLocked(null);
2505                if (r != null) {
2506                    setFocusedActivityLocked(r);
2507                }
2508            }
2509        }
2510    }
2511
2512    @Override
2513    public void notifyActivityDrawn(IBinder token) {
2514        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2515        synchronized (this) {
2516            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2517            if (r != null) {
2518                r.task.stack.notifyActivityDrawnLocked(r);
2519            }
2520        }
2521    }
2522
2523    final void applyUpdateLockStateLocked(ActivityRecord r) {
2524        // Modifications to the UpdateLock state are done on our handler, outside
2525        // the activity manager's locks.  The new state is determined based on the
2526        // state *now* of the relevant activity record.  The object is passed to
2527        // the handler solely for logging detail, not to be consulted/modified.
2528        final boolean nextState = r != null && r.immersive;
2529        mHandler.sendMessage(
2530                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2531    }
2532
2533    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2534        Message msg = Message.obtain();
2535        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2536        msg.obj = r.task.askedCompatMode ? null : r;
2537        mHandler.sendMessage(msg);
2538    }
2539
2540    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2541            String what, Object obj, ProcessRecord srcApp) {
2542        app.lastActivityTime = now;
2543
2544        if (app.activities.size() > 0) {
2545            // Don't want to touch dependent processes that are hosting activities.
2546            return index;
2547        }
2548
2549        int lrui = mLruProcesses.lastIndexOf(app);
2550        if (lrui < 0) {
2551            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2552                    + what + " " + obj + " from " + srcApp);
2553            return index;
2554        }
2555
2556        if (lrui >= index) {
2557            // Don't want to cause this to move dependent processes *back* in the
2558            // list as if they were less frequently used.
2559            return index;
2560        }
2561
2562        if (lrui >= mLruProcessActivityStart) {
2563            // Don't want to touch dependent processes that are hosting activities.
2564            return index;
2565        }
2566
2567        mLruProcesses.remove(lrui);
2568        if (index > 0) {
2569            index--;
2570        }
2571        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2572                + " in LRU list: " + app);
2573        mLruProcesses.add(index, app);
2574        return index;
2575    }
2576
2577    final void removeLruProcessLocked(ProcessRecord app) {
2578        int lrui = mLruProcesses.lastIndexOf(app);
2579        if (lrui >= 0) {
2580            if (lrui <= mLruProcessActivityStart) {
2581                mLruProcessActivityStart--;
2582            }
2583            if (lrui <= mLruProcessServiceStart) {
2584                mLruProcessServiceStart--;
2585            }
2586            mLruProcesses.remove(lrui);
2587        }
2588    }
2589
2590    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2591            ProcessRecord client) {
2592        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2593                || app.treatLikeActivity;
2594        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2595        if (!activityChange && hasActivity) {
2596            // The process has activities, so we are only allowing activity-based adjustments
2597            // to move it.  It should be kept in the front of the list with other
2598            // processes that have activities, and we don't want those to change their
2599            // order except due to activity operations.
2600            return;
2601        }
2602
2603        mLruSeq++;
2604        final long now = SystemClock.uptimeMillis();
2605        app.lastActivityTime = now;
2606
2607        // First a quick reject: if the app is already at the position we will
2608        // put it, then there is nothing to do.
2609        if (hasActivity) {
2610            final int N = mLruProcesses.size();
2611            if (N > 0 && mLruProcesses.get(N-1) == app) {
2612                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2613                return;
2614            }
2615        } else {
2616            if (mLruProcessServiceStart > 0
2617                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2618                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2619                return;
2620            }
2621        }
2622
2623        int lrui = mLruProcesses.lastIndexOf(app);
2624
2625        if (app.persistent && lrui >= 0) {
2626            // We don't care about the position of persistent processes, as long as
2627            // they are in the list.
2628            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2629            return;
2630        }
2631
2632        /* In progress: compute new position first, so we can avoid doing work
2633           if the process is not actually going to move.  Not yet working.
2634        int addIndex;
2635        int nextIndex;
2636        boolean inActivity = false, inService = false;
2637        if (hasActivity) {
2638            // Process has activities, put it at the very tipsy-top.
2639            addIndex = mLruProcesses.size();
2640            nextIndex = mLruProcessServiceStart;
2641            inActivity = true;
2642        } else if (hasService) {
2643            // Process has services, put it at the top of the service list.
2644            addIndex = mLruProcessActivityStart;
2645            nextIndex = mLruProcessServiceStart;
2646            inActivity = true;
2647            inService = true;
2648        } else  {
2649            // Process not otherwise of interest, it goes to the top of the non-service area.
2650            addIndex = mLruProcessServiceStart;
2651            if (client != null) {
2652                int clientIndex = mLruProcesses.lastIndexOf(client);
2653                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2654                        + app);
2655                if (clientIndex >= 0 && addIndex > clientIndex) {
2656                    addIndex = clientIndex;
2657                }
2658            }
2659            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2660        }
2661
2662        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2663                + mLruProcessActivityStart + "): " + app);
2664        */
2665
2666        if (lrui >= 0) {
2667            if (lrui < mLruProcessActivityStart) {
2668                mLruProcessActivityStart--;
2669            }
2670            if (lrui < mLruProcessServiceStart) {
2671                mLruProcessServiceStart--;
2672            }
2673            /*
2674            if (addIndex > lrui) {
2675                addIndex--;
2676            }
2677            if (nextIndex > lrui) {
2678                nextIndex--;
2679            }
2680            */
2681            mLruProcesses.remove(lrui);
2682        }
2683
2684        /*
2685        mLruProcesses.add(addIndex, app);
2686        if (inActivity) {
2687            mLruProcessActivityStart++;
2688        }
2689        if (inService) {
2690            mLruProcessActivityStart++;
2691        }
2692        */
2693
2694        int nextIndex;
2695        if (hasActivity) {
2696            final int N = mLruProcesses.size();
2697            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2698                // Process doesn't have activities, but has clients with
2699                // activities...  move it up, but one below the top (the top
2700                // should always have a real activity).
2701                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2702                mLruProcesses.add(N-1, app);
2703                // To keep it from spamming the LRU list (by making a bunch of clients),
2704                // we will push down any other entries owned by the app.
2705                final int uid = app.info.uid;
2706                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2707                    ProcessRecord subProc = mLruProcesses.get(i);
2708                    if (subProc.info.uid == uid) {
2709                        // We want to push this one down the list.  If the process after
2710                        // it is for the same uid, however, don't do so, because we don't
2711                        // want them internally to be re-ordered.
2712                        if (mLruProcesses.get(i-1).info.uid != uid) {
2713                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2714                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2715                            ProcessRecord tmp = mLruProcesses.get(i);
2716                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2717                            mLruProcesses.set(i-1, tmp);
2718                            i--;
2719                        }
2720                    } else {
2721                        // A gap, we can stop here.
2722                        break;
2723                    }
2724                }
2725            } else {
2726                // Process has activities, put it at the very tipsy-top.
2727                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2728                mLruProcesses.add(app);
2729            }
2730            nextIndex = mLruProcessServiceStart;
2731        } else if (hasService) {
2732            // Process has services, put it at the top of the service list.
2733            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2734            mLruProcesses.add(mLruProcessActivityStart, app);
2735            nextIndex = mLruProcessServiceStart;
2736            mLruProcessActivityStart++;
2737        } else  {
2738            // Process not otherwise of interest, it goes to the top of the non-service area.
2739            int index = mLruProcessServiceStart;
2740            if (client != null) {
2741                // If there is a client, don't allow the process to be moved up higher
2742                // in the list than that client.
2743                int clientIndex = mLruProcesses.lastIndexOf(client);
2744                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2745                        + " when updating " + app);
2746                if (clientIndex <= lrui) {
2747                    // Don't allow the client index restriction to push it down farther in the
2748                    // list than it already is.
2749                    clientIndex = lrui;
2750                }
2751                if (clientIndex >= 0 && index > clientIndex) {
2752                    index = clientIndex;
2753                }
2754            }
2755            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2756            mLruProcesses.add(index, app);
2757            nextIndex = index-1;
2758            mLruProcessActivityStart++;
2759            mLruProcessServiceStart++;
2760        }
2761
2762        // If the app is currently using a content provider or service,
2763        // bump those processes as well.
2764        for (int j=app.connections.size()-1; j>=0; j--) {
2765            ConnectionRecord cr = app.connections.valueAt(j);
2766            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2767                    && cr.binding.service.app != null
2768                    && cr.binding.service.app.lruSeq != mLruSeq
2769                    && !cr.binding.service.app.persistent) {
2770                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2771                        "service connection", cr, app);
2772            }
2773        }
2774        for (int j=app.conProviders.size()-1; j>=0; j--) {
2775            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2776            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2777                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2778                        "provider reference", cpr, app);
2779            }
2780        }
2781    }
2782
2783    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2784        if (uid == Process.SYSTEM_UID) {
2785            // The system gets to run in any process.  If there are multiple
2786            // processes with the same uid, just pick the first (this
2787            // should never happen).
2788            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2789            if (procs == null) return null;
2790            final int N = procs.size();
2791            for (int i = 0; i < N; i++) {
2792                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2793            }
2794        }
2795        ProcessRecord proc = mProcessNames.get(processName, uid);
2796        if (false && proc != null && !keepIfLarge
2797                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2798                && proc.lastCachedPss >= 4000) {
2799            // Turn this condition on to cause killing to happen regularly, for testing.
2800            if (proc.baseProcessTracker != null) {
2801                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2802            }
2803            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2804                    + "k from cached");
2805        } else if (proc != null && !keepIfLarge
2806                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2807                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2808            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2809            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2810                if (proc.baseProcessTracker != null) {
2811                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2812                }
2813                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2814                        + "k from cached");
2815            }
2816        }
2817        return proc;
2818    }
2819
2820    void ensurePackageDexOpt(String packageName) {
2821        IPackageManager pm = AppGlobals.getPackageManager();
2822        try {
2823            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2824                mDidDexOpt = true;
2825            }
2826        } catch (RemoteException e) {
2827        }
2828    }
2829
2830    boolean isNextTransitionForward() {
2831        int transit = mWindowManager.getPendingAppTransition();
2832        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2833                || transit == AppTransition.TRANSIT_TASK_OPEN
2834                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2835    }
2836
2837    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2838            String processName, String abiOverride, int uid, Runnable crashHandler) {
2839        synchronized(this) {
2840            ApplicationInfo info = new ApplicationInfo();
2841            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2842            // For isolated processes, the former contains the parent's uid and the latter the
2843            // actual uid of the isolated process.
2844            // In the special case introduced by this method (which is, starting an isolated
2845            // process directly from the SystemServer without an actual parent app process) the
2846            // closest thing to a parent's uid is SYSTEM_UID.
2847            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2848            // the |isolated| logic in the ProcessRecord constructor.
2849            info.uid = Process.SYSTEM_UID;
2850            info.processName = processName;
2851            info.className = entryPoint;
2852            info.packageName = "android";
2853            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2854                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2855                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2856                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2857                    crashHandler);
2858            return proc != null ? proc.pid : 0;
2859        }
2860    }
2861
2862    final ProcessRecord startProcessLocked(String processName,
2863            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2864            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2865            boolean isolated, boolean keepIfLarge) {
2866        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2867                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2868                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2869                null /* crashHandler */);
2870    }
2871
2872    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2873            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2874            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2875            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2876        ProcessRecord app;
2877        if (!isolated) {
2878            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2879        } else {
2880            // If this is an isolated process, it can't re-use an existing process.
2881            app = null;
2882        }
2883        // We don't have to do anything more if:
2884        // (1) There is an existing application record; and
2885        // (2) The caller doesn't think it is dead, OR there is no thread
2886        //     object attached to it so we know it couldn't have crashed; and
2887        // (3) There is a pid assigned to it, so it is either starting or
2888        //     already running.
2889        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2890                + " app=" + app + " knownToBeDead=" + knownToBeDead
2891                + " thread=" + (app != null ? app.thread : null)
2892                + " pid=" + (app != null ? app.pid : -1));
2893        if (app != null && app.pid > 0) {
2894            if (!knownToBeDead || app.thread == null) {
2895                // We already have the app running, or are waiting for it to
2896                // come up (we have a pid but not yet its thread), so keep it.
2897                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2898                // If this is a new package in the process, add the package to the list
2899                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2900                return app;
2901            }
2902
2903            // An application record is attached to a previous process,
2904            // clean it up now.
2905            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2906            Process.killProcessGroup(app.info.uid, app.pid);
2907            handleAppDiedLocked(app, true, true);
2908        }
2909
2910        String hostingNameStr = hostingName != null
2911                ? hostingName.flattenToShortString() : null;
2912
2913        if (!isolated) {
2914            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2915                // If we are in the background, then check to see if this process
2916                // is bad.  If so, we will just silently fail.
2917                if (mBadProcesses.get(info.processName, info.uid) != null) {
2918                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2919                            + "/" + info.processName);
2920                    return null;
2921                }
2922            } else {
2923                // When the user is explicitly starting a process, then clear its
2924                // crash count so that we won't make it bad until they see at
2925                // least one crash dialog again, and make the process good again
2926                // if it had been bad.
2927                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2928                        + "/" + info.processName);
2929                mProcessCrashTimes.remove(info.processName, info.uid);
2930                if (mBadProcesses.get(info.processName, info.uid) != null) {
2931                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2932                            UserHandle.getUserId(info.uid), info.uid,
2933                            info.processName);
2934                    mBadProcesses.remove(info.processName, info.uid);
2935                    if (app != null) {
2936                        app.bad = false;
2937                    }
2938                }
2939            }
2940        }
2941
2942        if (app == null) {
2943            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2944            app.crashHandler = crashHandler;
2945            if (app == null) {
2946                Slog.w(TAG, "Failed making new process record for "
2947                        + processName + "/" + info.uid + " isolated=" + isolated);
2948                return null;
2949            }
2950            mProcessNames.put(processName, app.uid, app);
2951            if (isolated) {
2952                mIsolatedProcesses.put(app.uid, app);
2953            }
2954        } else {
2955            // If this is a new package in the process, add the package to the list
2956            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2957        }
2958
2959        // If the system is not ready yet, then hold off on starting this
2960        // process until it is.
2961        if (!mProcessesReady
2962                && !isAllowedWhileBooting(info)
2963                && !allowWhileBooting) {
2964            if (!mProcessesOnHold.contains(app)) {
2965                mProcessesOnHold.add(app);
2966            }
2967            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2968            return app;
2969        }
2970
2971        startProcessLocked(
2972                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2973        return (app.pid != 0) ? app : null;
2974    }
2975
2976    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2977        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2978    }
2979
2980    private final void startProcessLocked(ProcessRecord app,
2981            String hostingType, String hostingNameStr) {
2982        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2983                null /* entryPoint */, null /* entryPointArgs */);
2984    }
2985
2986    private final void startProcessLocked(ProcessRecord app, String hostingType,
2987            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2988        if (app.pid > 0 && app.pid != MY_PID) {
2989            synchronized (mPidsSelfLocked) {
2990                mPidsSelfLocked.remove(app.pid);
2991                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2992            }
2993            app.setPid(0);
2994        }
2995
2996        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2997                "startProcessLocked removing on hold: " + app);
2998        mProcessesOnHold.remove(app);
2999
3000        updateCpuStats();
3001
3002        try {
3003            int uid = app.uid;
3004
3005            int[] gids = null;
3006            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3007            if (!app.isolated) {
3008                int[] permGids = null;
3009                try {
3010                    final PackageManager pm = mContext.getPackageManager();
3011                    permGids = pm.getPackageGids(app.info.packageName);
3012
3013                    if (Environment.isExternalStorageEmulated()) {
3014                        if (pm.checkPermission(
3015                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3016                                app.info.packageName) == PERMISSION_GRANTED) {
3017                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3018                        } else {
3019                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3020                        }
3021                    }
3022                } catch (PackageManager.NameNotFoundException e) {
3023                    Slog.w(TAG, "Unable to retrieve gids", e);
3024                }
3025
3026                /*
3027                 * Add shared application and profile GIDs so applications can share some
3028                 * resources like shared libraries and access user-wide resources
3029                 */
3030                if (permGids == null) {
3031                    gids = new int[2];
3032                } else {
3033                    gids = new int[permGids.length + 2];
3034                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3035                }
3036                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3037                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3038            }
3039            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3040                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3041                        && mTopComponent != null
3042                        && app.processName.equals(mTopComponent.getPackageName())) {
3043                    uid = 0;
3044                }
3045                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3046                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3047                    uid = 0;
3048                }
3049            }
3050            int debugFlags = 0;
3051            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3052                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3053                // Also turn on CheckJNI for debuggable apps. It's quite
3054                // awkward to turn on otherwise.
3055                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3056            }
3057            // Run the app in safe mode if its manifest requests so or the
3058            // system is booted in safe mode.
3059            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3060                mSafeMode == true) {
3061                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3062            }
3063            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3064                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3065            }
3066            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3067                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3068            }
3069            if ("1".equals(SystemProperties.get("debug.assert"))) {
3070                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3071            }
3072
3073            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3074            if (requiredAbi == null) {
3075                requiredAbi = Build.SUPPORTED_ABIS[0];
3076            }
3077
3078            // Start the process.  It will either succeed and return a result containing
3079            // the PID of the new process, or else throw a RuntimeException.
3080            boolean isActivityProcess = (entryPoint == null);
3081            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3082            Process.ProcessStartResult startResult = Process.start(entryPoint,
3083                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3084                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3085
3086            if (app.isolated) {
3087                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3088            }
3089            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3090
3091            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3092                    UserHandle.getUserId(uid), startResult.pid, uid,
3093                    app.processName, hostingType,
3094                    hostingNameStr != null ? hostingNameStr : "");
3095
3096            if (app.persistent) {
3097                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3098            }
3099
3100            StringBuilder buf = mStringBuilder;
3101            buf.setLength(0);
3102            buf.append("Start proc ");
3103            buf.append(app.processName);
3104            if (!isActivityProcess) {
3105                buf.append(" [");
3106                buf.append(entryPoint);
3107                buf.append("]");
3108            }
3109            buf.append(" for ");
3110            buf.append(hostingType);
3111            if (hostingNameStr != null) {
3112                buf.append(" ");
3113                buf.append(hostingNameStr);
3114            }
3115            buf.append(": pid=");
3116            buf.append(startResult.pid);
3117            buf.append(" uid=");
3118            buf.append(uid);
3119            buf.append(" gids={");
3120            if (gids != null) {
3121                for (int gi=0; gi<gids.length; gi++) {
3122                    if (gi != 0) buf.append(", ");
3123                    buf.append(gids[gi]);
3124
3125                }
3126            }
3127            buf.append("}");
3128            if (requiredAbi != null) {
3129                buf.append(" abi=");
3130                buf.append(requiredAbi);
3131            }
3132            Slog.i(TAG, buf.toString());
3133            app.setPid(startResult.pid);
3134            app.usingWrapper = startResult.usingWrapper;
3135            app.removed = false;
3136            app.killedByAm = false;
3137            synchronized (mPidsSelfLocked) {
3138                this.mPidsSelfLocked.put(startResult.pid, app);
3139                if (isActivityProcess) {
3140                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3141                    msg.obj = app;
3142                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3143                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3144                }
3145            }
3146        } catch (RuntimeException e) {
3147            // XXX do better error recovery.
3148            app.setPid(0);
3149            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3150            if (app.isolated) {
3151                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3152            }
3153            Slog.e(TAG, "Failure starting process " + app.processName, e);
3154        }
3155    }
3156
3157    void updateUsageStats(ActivityRecord component, boolean resumed) {
3158        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3159        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3160        if (resumed) {
3161            if (mUsageStatsService != null) {
3162                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3163                        System.currentTimeMillis(),
3164                        UsageStats.Event.MOVE_TO_FOREGROUND);
3165            }
3166            synchronized (stats) {
3167                stats.noteActivityResumedLocked(component.app.uid);
3168            }
3169        } else {
3170            if (mUsageStatsService != null) {
3171                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3172                        System.currentTimeMillis(),
3173                        UsageStats.Event.MOVE_TO_BACKGROUND);
3174            }
3175            synchronized (stats) {
3176                stats.noteActivityPausedLocked(component.app.uid);
3177            }
3178        }
3179    }
3180
3181    Intent getHomeIntent() {
3182        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3183        intent.setComponent(mTopComponent);
3184        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3185            intent.addCategory(Intent.CATEGORY_HOME);
3186        }
3187        return intent;
3188    }
3189
3190    boolean startHomeActivityLocked(int userId) {
3191        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3192                && mTopAction == null) {
3193            // We are running in factory test mode, but unable to find
3194            // the factory test app, so just sit around displaying the
3195            // error message and don't try to start anything.
3196            return false;
3197        }
3198        Intent intent = getHomeIntent();
3199        ActivityInfo aInfo =
3200            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3201        if (aInfo != null) {
3202            intent.setComponent(new ComponentName(
3203                    aInfo.applicationInfo.packageName, aInfo.name));
3204            // Don't do this if the home app is currently being
3205            // instrumented.
3206            aInfo = new ActivityInfo(aInfo);
3207            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3208            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3209                    aInfo.applicationInfo.uid, true);
3210            if (app == null || app.instrumentationClass == null) {
3211                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3212                mStackSupervisor.startHomeActivity(intent, aInfo);
3213            }
3214        }
3215
3216        return true;
3217    }
3218
3219    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3220        ActivityInfo ai = null;
3221        ComponentName comp = intent.getComponent();
3222        try {
3223            if (comp != null) {
3224                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3225            } else {
3226                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3227                        intent,
3228                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3229                            flags, userId);
3230
3231                if (info != null) {
3232                    ai = info.activityInfo;
3233                }
3234            }
3235        } catch (RemoteException e) {
3236            // ignore
3237        }
3238
3239        return ai;
3240    }
3241
3242    /**
3243     * Starts the "new version setup screen" if appropriate.
3244     */
3245    void startSetupActivityLocked() {
3246        // Only do this once per boot.
3247        if (mCheckedForSetup) {
3248            return;
3249        }
3250
3251        // We will show this screen if the current one is a different
3252        // version than the last one shown, and we are not running in
3253        // low-level factory test mode.
3254        final ContentResolver resolver = mContext.getContentResolver();
3255        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3256                Settings.Global.getInt(resolver,
3257                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3258            mCheckedForSetup = true;
3259
3260            // See if we should be showing the platform update setup UI.
3261            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3262            List<ResolveInfo> ris = mContext.getPackageManager()
3263                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3264
3265            // We don't allow third party apps to replace this.
3266            ResolveInfo ri = null;
3267            for (int i=0; ris != null && i<ris.size(); i++) {
3268                if ((ris.get(i).activityInfo.applicationInfo.flags
3269                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3270                    ri = ris.get(i);
3271                    break;
3272                }
3273            }
3274
3275            if (ri != null) {
3276                String vers = ri.activityInfo.metaData != null
3277                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3278                        : null;
3279                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3280                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3281                            Intent.METADATA_SETUP_VERSION);
3282                }
3283                String lastVers = Settings.Secure.getString(
3284                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3285                if (vers != null && !vers.equals(lastVers)) {
3286                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3287                    intent.setComponent(new ComponentName(
3288                            ri.activityInfo.packageName, ri.activityInfo.name));
3289                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3290                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3291                }
3292            }
3293        }
3294    }
3295
3296    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3297        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3298    }
3299
3300    void enforceNotIsolatedCaller(String caller) {
3301        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3302            throw new SecurityException("Isolated process not allowed to call " + caller);
3303        }
3304    }
3305
3306    @Override
3307    public int getFrontActivityScreenCompatMode() {
3308        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3309        synchronized (this) {
3310            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3311        }
3312    }
3313
3314    @Override
3315    public void setFrontActivityScreenCompatMode(int mode) {
3316        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3317                "setFrontActivityScreenCompatMode");
3318        synchronized (this) {
3319            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3320        }
3321    }
3322
3323    @Override
3324    public int getPackageScreenCompatMode(String packageName) {
3325        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3326        synchronized (this) {
3327            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3328        }
3329    }
3330
3331    @Override
3332    public void setPackageScreenCompatMode(String packageName, int mode) {
3333        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3334                "setPackageScreenCompatMode");
3335        synchronized (this) {
3336            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3337        }
3338    }
3339
3340    @Override
3341    public boolean getPackageAskScreenCompat(String packageName) {
3342        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3343        synchronized (this) {
3344            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3345        }
3346    }
3347
3348    @Override
3349    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3350        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3351                "setPackageAskScreenCompat");
3352        synchronized (this) {
3353            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3354        }
3355    }
3356
3357    private void dispatchProcessesChanged() {
3358        int N;
3359        synchronized (this) {
3360            N = mPendingProcessChanges.size();
3361            if (mActiveProcessChanges.length < N) {
3362                mActiveProcessChanges = new ProcessChangeItem[N];
3363            }
3364            mPendingProcessChanges.toArray(mActiveProcessChanges);
3365            mAvailProcessChanges.addAll(mPendingProcessChanges);
3366            mPendingProcessChanges.clear();
3367            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3368        }
3369
3370        int i = mProcessObservers.beginBroadcast();
3371        while (i > 0) {
3372            i--;
3373            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3374            if (observer != null) {
3375                try {
3376                    for (int j=0; j<N; j++) {
3377                        ProcessChangeItem item = mActiveProcessChanges[j];
3378                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3379                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3380                                    + item.pid + " uid=" + item.uid + ": "
3381                                    + item.foregroundActivities);
3382                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3383                                    item.foregroundActivities);
3384                        }
3385                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3386                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3387                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3388                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3389                        }
3390                    }
3391                } catch (RemoteException e) {
3392                }
3393            }
3394        }
3395        mProcessObservers.finishBroadcast();
3396    }
3397
3398    private void dispatchProcessDied(int pid, int uid) {
3399        int i = mProcessObservers.beginBroadcast();
3400        while (i > 0) {
3401            i--;
3402            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3403            if (observer != null) {
3404                try {
3405                    observer.onProcessDied(pid, uid);
3406                } catch (RemoteException e) {
3407                }
3408            }
3409        }
3410        mProcessObservers.finishBroadcast();
3411    }
3412
3413    @Override
3414    public final int startActivity(IApplicationThread caller, String callingPackage,
3415            Intent intent, String resolvedType, IBinder resultTo,
3416            String resultWho, int requestCode, int startFlags,
3417            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3418        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3419                resultWho, requestCode,
3420                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3421    }
3422
3423    @Override
3424    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3425            Intent intent, String resolvedType, IBinder resultTo,
3426            String resultWho, int requestCode, int startFlags,
3427            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3428        enforceNotIsolatedCaller("startActivity");
3429        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3430                false, ALLOW_FULL_ONLY, "startActivity", null);
3431        // TODO: Switch to user app stacks here.
3432        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3433                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3434                null, null, options, userId, null);
3435    }
3436
3437    @Override
3438    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3439            Intent intent, String resolvedType, IBinder resultTo,
3440            String resultWho, int requestCode, int startFlags, String profileFile,
3441            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3442        enforceNotIsolatedCaller("startActivityAndWait");
3443        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3444                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3445        WaitResult res = new WaitResult();
3446        // TODO: Switch to user app stacks here.
3447        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3448                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3449                res, null, options, userId, null);
3450        return res;
3451    }
3452
3453    @Override
3454    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3455            Intent intent, String resolvedType, IBinder resultTo,
3456            String resultWho, int requestCode, int startFlags, Configuration config,
3457            Bundle options, int userId) {
3458        enforceNotIsolatedCaller("startActivityWithConfig");
3459        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3460                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3461        // TODO: Switch to user app stacks here.
3462        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3463                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3464                null, null, null, config, options, userId, null);
3465        return ret;
3466    }
3467
3468    @Override
3469    public int startActivityIntentSender(IApplicationThread caller,
3470            IntentSender intent, Intent fillInIntent, String resolvedType,
3471            IBinder resultTo, String resultWho, int requestCode,
3472            int flagsMask, int flagsValues, Bundle options) {
3473        enforceNotIsolatedCaller("startActivityIntentSender");
3474        // Refuse possible leaked file descriptors
3475        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3476            throw new IllegalArgumentException("File descriptors passed in Intent");
3477        }
3478
3479        IIntentSender sender = intent.getTarget();
3480        if (!(sender instanceof PendingIntentRecord)) {
3481            throw new IllegalArgumentException("Bad PendingIntent object");
3482        }
3483
3484        PendingIntentRecord pir = (PendingIntentRecord)sender;
3485
3486        synchronized (this) {
3487            // If this is coming from the currently resumed activity, it is
3488            // effectively saying that app switches are allowed at this point.
3489            final ActivityStack stack = getFocusedStack();
3490            if (stack.mResumedActivity != null &&
3491                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3492                mAppSwitchesAllowedTime = 0;
3493            }
3494        }
3495        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3496                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3497        return ret;
3498    }
3499
3500    @Override
3501    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3502            Intent intent, String resolvedType, IVoiceInteractionSession session,
3503            IVoiceInteractor interactor, int startFlags, String profileFile,
3504            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3505        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3506                != PackageManager.PERMISSION_GRANTED) {
3507            String msg = "Permission Denial: startVoiceActivity() from pid="
3508                    + Binder.getCallingPid()
3509                    + ", uid=" + Binder.getCallingUid()
3510                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3511            Slog.w(TAG, msg);
3512            throw new SecurityException(msg);
3513        }
3514        if (session == null || interactor == null) {
3515            throw new NullPointerException("null session or interactor");
3516        }
3517        userId = handleIncomingUser(callingPid, callingUid, userId,
3518                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3519        // TODO: Switch to user app stacks here.
3520        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3521                resolvedType, session, interactor, null, null, 0, startFlags,
3522                profileFile, profileFd, null, null, options, userId, null);
3523    }
3524
3525    @Override
3526    public boolean startNextMatchingActivity(IBinder callingActivity,
3527            Intent intent, Bundle options) {
3528        // Refuse possible leaked file descriptors
3529        if (intent != null && intent.hasFileDescriptors() == true) {
3530            throw new IllegalArgumentException("File descriptors passed in Intent");
3531        }
3532
3533        synchronized (this) {
3534            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3535            if (r == null) {
3536                ActivityOptions.abort(options);
3537                return false;
3538            }
3539            if (r.app == null || r.app.thread == null) {
3540                // The caller is not running...  d'oh!
3541                ActivityOptions.abort(options);
3542                return false;
3543            }
3544            intent = new Intent(intent);
3545            // The caller is not allowed to change the data.
3546            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3547            // And we are resetting to find the next component...
3548            intent.setComponent(null);
3549
3550            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3551
3552            ActivityInfo aInfo = null;
3553            try {
3554                List<ResolveInfo> resolves =
3555                    AppGlobals.getPackageManager().queryIntentActivities(
3556                            intent, r.resolvedType,
3557                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3558                            UserHandle.getCallingUserId());
3559
3560                // Look for the original activity in the list...
3561                final int N = resolves != null ? resolves.size() : 0;
3562                for (int i=0; i<N; i++) {
3563                    ResolveInfo rInfo = resolves.get(i);
3564                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3565                            && rInfo.activityInfo.name.equals(r.info.name)) {
3566                        // We found the current one...  the next matching is
3567                        // after it.
3568                        i++;
3569                        if (i<N) {
3570                            aInfo = resolves.get(i).activityInfo;
3571                        }
3572                        if (debug) {
3573                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3574                                    + "/" + r.info.name);
3575                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3576                                    + "/" + aInfo.name);
3577                        }
3578                        break;
3579                    }
3580                }
3581            } catch (RemoteException e) {
3582            }
3583
3584            if (aInfo == null) {
3585                // Nobody who is next!
3586                ActivityOptions.abort(options);
3587                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3588                return false;
3589            }
3590
3591            intent.setComponent(new ComponentName(
3592                    aInfo.applicationInfo.packageName, aInfo.name));
3593            intent.setFlags(intent.getFlags()&~(
3594                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3595                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3596                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3597                    Intent.FLAG_ACTIVITY_NEW_TASK));
3598
3599            // Okay now we need to start the new activity, replacing the
3600            // currently running activity.  This is a little tricky because
3601            // we want to start the new one as if the current one is finished,
3602            // but not finish the current one first so that there is no flicker.
3603            // And thus...
3604            final boolean wasFinishing = r.finishing;
3605            r.finishing = true;
3606
3607            // Propagate reply information over to the new activity.
3608            final ActivityRecord resultTo = r.resultTo;
3609            final String resultWho = r.resultWho;
3610            final int requestCode = r.requestCode;
3611            r.resultTo = null;
3612            if (resultTo != null) {
3613                resultTo.removeResultsLocked(r, resultWho, requestCode);
3614            }
3615
3616            final long origId = Binder.clearCallingIdentity();
3617            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3618                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3619                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3620                    options, false, null, null);
3621            Binder.restoreCallingIdentity(origId);
3622
3623            r.finishing = wasFinishing;
3624            if (res != ActivityManager.START_SUCCESS) {
3625                return false;
3626            }
3627            return true;
3628        }
3629    }
3630
3631    @Override
3632    public final int startActivityFromRecents(int taskId, Bundle options) {
3633        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3634            String msg = "Permission Denial: startActivityFromRecents called without " +
3635                    START_TASKS_FROM_RECENTS;
3636            Slog.w(TAG, msg);
3637            throw new SecurityException(msg);
3638        }
3639        final int callingUid;
3640        final String callingPackage;
3641        final Intent intent;
3642        final int userId;
3643        synchronized (this) {
3644            final TaskRecord task = recentTaskForIdLocked(taskId);
3645            if (task == null) {
3646                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3647            }
3648            callingUid = task.mCallingUid;
3649            callingPackage = task.mCallingPackage;
3650            intent = task.intent;
3651            userId = task.userId;
3652        }
3653        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3654                options, userId, null);
3655    }
3656
3657    final int startActivityInPackage(int uid, String callingPackage,
3658            Intent intent, String resolvedType, IBinder resultTo,
3659            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3660                    IActivityContainer container) {
3661
3662        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3663                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3664
3665        // TODO: Switch to user app stacks here.
3666        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3667                null, null, resultTo, resultWho, requestCode, startFlags,
3668                null, null, null, null, options, userId, container);
3669        return ret;
3670    }
3671
3672    @Override
3673    public final int startActivities(IApplicationThread caller, String callingPackage,
3674            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3675            int userId) {
3676        enforceNotIsolatedCaller("startActivities");
3677        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3678                false, ALLOW_FULL_ONLY, "startActivity", null);
3679        // TODO: Switch to user app stacks here.
3680        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3681                resolvedTypes, resultTo, options, userId);
3682        return ret;
3683    }
3684
3685    final int startActivitiesInPackage(int uid, String callingPackage,
3686            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3687            Bundle options, int userId) {
3688
3689        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3690                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3691        // TODO: Switch to user app stacks here.
3692        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3693                resultTo, options, userId);
3694        return ret;
3695    }
3696
3697    //explicitly remove thd old information in mRecentTasks when removing existing user.
3698    private void removeRecentTasksForUserLocked(int userId) {
3699        if(userId <= 0) {
3700            Slog.i(TAG, "Can't remove recent task on user " + userId);
3701            return;
3702        }
3703
3704        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3705            TaskRecord tr = mRecentTasks.get(i);
3706            if (tr.userId == userId) {
3707                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3708                        + " when finishing user" + userId);
3709                tr.disposeThumbnail();
3710                mRecentTasks.remove(i);
3711            }
3712        }
3713
3714        // Remove tasks from persistent storage.
3715        mTaskPersister.wakeup(null, true);
3716    }
3717
3718    final void addRecentTaskLocked(TaskRecord task) {
3719        int N = mRecentTasks.size();
3720        // Quick case: check if the top-most recent task is the same.
3721        if (N > 0 && mRecentTasks.get(0) == task) {
3722            return;
3723        }
3724        // Another quick case: never add voice sessions.
3725        if (task.voiceSession != null) {
3726            return;
3727        }
3728        // Remove any existing entries that are the same kind of task.
3729        final Intent intent = task.intent;
3730        final boolean document = intent != null && intent.isDocument();
3731        final ComponentName comp = intent.getComponent();
3732
3733        int maxRecents = task.maxRecents - 1;
3734        for (int i=0; i<N; i++) {
3735            final TaskRecord tr = mRecentTasks.get(i);
3736            if (task != tr) {
3737                if (task.userId != tr.userId) {
3738                    continue;
3739                }
3740                if (i > MAX_RECENT_BITMAPS) {
3741                    tr.freeLastThumbnail();
3742                }
3743                final Intent trIntent = tr.intent;
3744                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3745                    (intent == null || !intent.filterEquals(trIntent))) {
3746                    continue;
3747                }
3748                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3749                if (document && trIsDocument) {
3750                    // These are the same document activity (not necessarily the same doc).
3751                    if (maxRecents > 0) {
3752                        --maxRecents;
3753                        continue;
3754                    }
3755                    // Hit the maximum number of documents for this task. Fall through
3756                    // and remove this document from recents.
3757                } else if (document || trIsDocument) {
3758                    // Only one of these is a document. Not the droid we're looking for.
3759                    continue;
3760                }
3761            }
3762
3763            // Either task and tr are the same or, their affinities match or their intents match
3764            // and neither of them is a document, or they are documents using the same activity
3765            // and their maxRecents has been reached.
3766            tr.disposeThumbnail();
3767            mRecentTasks.remove(i);
3768            if (task != tr) {
3769                tr.closeRecentsChain();
3770            }
3771            i--;
3772            N--;
3773            if (task.intent == null) {
3774                // If the new recent task we are adding is not fully
3775                // specified, then replace it with the existing recent task.
3776                task = tr;
3777            }
3778            notifyTaskPersisterLocked(tr, false);
3779        }
3780        if (N >= MAX_RECENT_TASKS) {
3781            final TaskRecord tr = mRecentTasks.remove(N - 1);
3782            tr.disposeThumbnail();
3783            tr.closeRecentsChain();
3784        }
3785        mRecentTasks.add(0, task);
3786    }
3787
3788    @Override
3789    public void reportActivityFullyDrawn(IBinder token) {
3790        synchronized (this) {
3791            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3792            if (r == null) {
3793                return;
3794            }
3795            r.reportFullyDrawnLocked();
3796        }
3797    }
3798
3799    @Override
3800    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3801        synchronized (this) {
3802            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3803            if (r == null) {
3804                return;
3805            }
3806            final long origId = Binder.clearCallingIdentity();
3807            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3808            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3809                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3810            if (config != null) {
3811                r.frozenBeforeDestroy = true;
3812                if (!updateConfigurationLocked(config, r, false, false)) {
3813                    mStackSupervisor.resumeTopActivitiesLocked();
3814                }
3815            }
3816            Binder.restoreCallingIdentity(origId);
3817        }
3818    }
3819
3820    @Override
3821    public int getRequestedOrientation(IBinder token) {
3822        synchronized (this) {
3823            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3824            if (r == null) {
3825                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3826            }
3827            return mWindowManager.getAppOrientation(r.appToken);
3828        }
3829    }
3830
3831    /**
3832     * This is the internal entry point for handling Activity.finish().
3833     *
3834     * @param token The Binder token referencing the Activity we want to finish.
3835     * @param resultCode Result code, if any, from this Activity.
3836     * @param resultData Result data (Intent), if any, from this Activity.
3837     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3838     *            the root Activity in the task.
3839     *
3840     * @return Returns true if the activity successfully finished, or false if it is still running.
3841     */
3842    @Override
3843    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3844            boolean finishTask) {
3845        // Refuse possible leaked file descriptors
3846        if (resultData != null && resultData.hasFileDescriptors() == true) {
3847            throw new IllegalArgumentException("File descriptors passed in Intent");
3848        }
3849
3850        synchronized(this) {
3851            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3852            if (r == null) {
3853                return true;
3854            }
3855            // Keep track of the root activity of the task before we finish it
3856            TaskRecord tr = r.task;
3857            ActivityRecord rootR = tr.getRootActivity();
3858            // Do not allow task to finish in Lock Task mode.
3859            if (tr == mStackSupervisor.mLockTaskModeTask) {
3860                if (rootR == r) {
3861                    mStackSupervisor.showLockTaskToast();
3862                    return false;
3863                }
3864            }
3865            if (mController != null) {
3866                // Find the first activity that is not finishing.
3867                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3868                if (next != null) {
3869                    // ask watcher if this is allowed
3870                    boolean resumeOK = true;
3871                    try {
3872                        resumeOK = mController.activityResuming(next.packageName);
3873                    } catch (RemoteException e) {
3874                        mController = null;
3875                        Watchdog.getInstance().setActivityController(null);
3876                    }
3877
3878                    if (!resumeOK) {
3879                        return false;
3880                    }
3881                }
3882            }
3883            final long origId = Binder.clearCallingIdentity();
3884            try {
3885                boolean res;
3886                if (finishTask && r == rootR) {
3887                    // If requested, remove the task that is associated to this activity only if it
3888                    // was the root activity in the task.  The result code and data is ignored because
3889                    // we don't support returning them across task boundaries.
3890                    res = removeTaskByIdLocked(tr.taskId, 0);
3891                } else {
3892                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3893                            resultData, "app-request", true);
3894                }
3895                return res;
3896            } finally {
3897                Binder.restoreCallingIdentity(origId);
3898            }
3899        }
3900    }
3901
3902    @Override
3903    public final void finishHeavyWeightApp() {
3904        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3905                != PackageManager.PERMISSION_GRANTED) {
3906            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3907                    + Binder.getCallingPid()
3908                    + ", uid=" + Binder.getCallingUid()
3909                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3910            Slog.w(TAG, msg);
3911            throw new SecurityException(msg);
3912        }
3913
3914        synchronized(this) {
3915            if (mHeavyWeightProcess == null) {
3916                return;
3917            }
3918
3919            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3920                    mHeavyWeightProcess.activities);
3921            for (int i=0; i<activities.size(); i++) {
3922                ActivityRecord r = activities.get(i);
3923                if (!r.finishing) {
3924                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3925                            null, "finish-heavy", true);
3926                }
3927            }
3928
3929            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3930                    mHeavyWeightProcess.userId, 0));
3931            mHeavyWeightProcess = null;
3932        }
3933    }
3934
3935    @Override
3936    public void crashApplication(int uid, int initialPid, String packageName,
3937            String message) {
3938        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3939                != PackageManager.PERMISSION_GRANTED) {
3940            String msg = "Permission Denial: crashApplication() from pid="
3941                    + Binder.getCallingPid()
3942                    + ", uid=" + Binder.getCallingUid()
3943                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3944            Slog.w(TAG, msg);
3945            throw new SecurityException(msg);
3946        }
3947
3948        synchronized(this) {
3949            ProcessRecord proc = null;
3950
3951            // Figure out which process to kill.  We don't trust that initialPid
3952            // still has any relation to current pids, so must scan through the
3953            // list.
3954            synchronized (mPidsSelfLocked) {
3955                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3956                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3957                    if (p.uid != uid) {
3958                        continue;
3959                    }
3960                    if (p.pid == initialPid) {
3961                        proc = p;
3962                        break;
3963                    }
3964                    if (p.pkgList.containsKey(packageName)) {
3965                        proc = p;
3966                    }
3967                }
3968            }
3969
3970            if (proc == null) {
3971                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3972                        + " initialPid=" + initialPid
3973                        + " packageName=" + packageName);
3974                return;
3975            }
3976
3977            if (proc.thread != null) {
3978                if (proc.pid == Process.myPid()) {
3979                    Log.w(TAG, "crashApplication: trying to crash self!");
3980                    return;
3981                }
3982                long ident = Binder.clearCallingIdentity();
3983                try {
3984                    proc.thread.scheduleCrash(message);
3985                } catch (RemoteException e) {
3986                }
3987                Binder.restoreCallingIdentity(ident);
3988            }
3989        }
3990    }
3991
3992    @Override
3993    public final void finishSubActivity(IBinder token, String resultWho,
3994            int requestCode) {
3995        synchronized(this) {
3996            final long origId = Binder.clearCallingIdentity();
3997            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3998            if (r != null) {
3999                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4000            }
4001            Binder.restoreCallingIdentity(origId);
4002        }
4003    }
4004
4005    @Override
4006    public boolean finishActivityAffinity(IBinder token) {
4007        synchronized(this) {
4008            final long origId = Binder.clearCallingIdentity();
4009            try {
4010                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4011
4012                ActivityRecord rootR = r.task.getRootActivity();
4013                // Do not allow task to finish in Lock Task mode.
4014                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4015                    if (rootR == r) {
4016                        mStackSupervisor.showLockTaskToast();
4017                        return false;
4018                    }
4019                }
4020                boolean res = false;
4021                if (r != null) {
4022                    res = r.task.stack.finishActivityAffinityLocked(r);
4023                }
4024                return res;
4025            } finally {
4026                Binder.restoreCallingIdentity(origId);
4027            }
4028        }
4029    }
4030
4031    @Override
4032    public void finishVoiceTask(IVoiceInteractionSession session) {
4033        synchronized(this) {
4034            final long origId = Binder.clearCallingIdentity();
4035            try {
4036                mStackSupervisor.finishVoiceTask(session);
4037            } finally {
4038                Binder.restoreCallingIdentity(origId);
4039            }
4040        }
4041
4042    }
4043
4044    @Override
4045    public boolean willActivityBeVisible(IBinder token) {
4046        synchronized(this) {
4047            ActivityStack stack = ActivityRecord.getStackLocked(token);
4048            if (stack != null) {
4049                return stack.willActivityBeVisibleLocked(token);
4050            }
4051            return false;
4052        }
4053    }
4054
4055    @Override
4056    public void overridePendingTransition(IBinder token, String packageName,
4057            int enterAnim, int exitAnim) {
4058        synchronized(this) {
4059            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4060            if (self == null) {
4061                return;
4062            }
4063
4064            final long origId = Binder.clearCallingIdentity();
4065
4066            if (self.state == ActivityState.RESUMED
4067                    || self.state == ActivityState.PAUSING) {
4068                mWindowManager.overridePendingAppTransition(packageName,
4069                        enterAnim, exitAnim, null);
4070            }
4071
4072            Binder.restoreCallingIdentity(origId);
4073        }
4074    }
4075
4076    /**
4077     * Main function for removing an existing process from the activity manager
4078     * as a result of that process going away.  Clears out all connections
4079     * to the process.
4080     */
4081    private final void handleAppDiedLocked(ProcessRecord app,
4082            boolean restarting, boolean allowRestart) {
4083        int pid = app.pid;
4084        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4085        if (!restarting) {
4086            removeLruProcessLocked(app);
4087            if (pid > 0) {
4088                ProcessList.remove(pid);
4089            }
4090        }
4091
4092        if (mProfileProc == app) {
4093            clearProfilerLocked();
4094        }
4095
4096        // Remove this application's activities from active lists.
4097        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4098
4099        app.activities.clear();
4100
4101        if (app.instrumentationClass != null) {
4102            Slog.w(TAG, "Crash of app " + app.processName
4103                  + " running instrumentation " + app.instrumentationClass);
4104            Bundle info = new Bundle();
4105            info.putString("shortMsg", "Process crashed.");
4106            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4107        }
4108
4109        if (!restarting) {
4110            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4111                // If there was nothing to resume, and we are not already
4112                // restarting this process, but there is a visible activity that
4113                // is hosted by the process...  then make sure all visible
4114                // activities are running, taking care of restarting this
4115                // process.
4116                if (hasVisibleActivities) {
4117                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4118                }
4119            }
4120        }
4121    }
4122
4123    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4124        IBinder threadBinder = thread.asBinder();
4125        // Find the application record.
4126        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4127            ProcessRecord rec = mLruProcesses.get(i);
4128            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4129                return i;
4130            }
4131        }
4132        return -1;
4133    }
4134
4135    final ProcessRecord getRecordForAppLocked(
4136            IApplicationThread thread) {
4137        if (thread == null) {
4138            return null;
4139        }
4140
4141        int appIndex = getLRURecordIndexForAppLocked(thread);
4142        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4143    }
4144
4145    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4146        // If there are no longer any background processes running,
4147        // and the app that died was not running instrumentation,
4148        // then tell everyone we are now low on memory.
4149        boolean haveBg = false;
4150        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4151            ProcessRecord rec = mLruProcesses.get(i);
4152            if (rec.thread != null
4153                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4154                haveBg = true;
4155                break;
4156            }
4157        }
4158
4159        if (!haveBg) {
4160            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4161            if (doReport) {
4162                long now = SystemClock.uptimeMillis();
4163                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4164                    doReport = false;
4165                } else {
4166                    mLastMemUsageReportTime = now;
4167                }
4168            }
4169            final ArrayList<ProcessMemInfo> memInfos
4170                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4171            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4172            long now = SystemClock.uptimeMillis();
4173            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4174                ProcessRecord rec = mLruProcesses.get(i);
4175                if (rec == dyingProc || rec.thread == null) {
4176                    continue;
4177                }
4178                if (doReport) {
4179                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4180                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4181                }
4182                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4183                    // The low memory report is overriding any current
4184                    // state for a GC request.  Make sure to do
4185                    // heavy/important/visible/foreground processes first.
4186                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4187                        rec.lastRequestedGc = 0;
4188                    } else {
4189                        rec.lastRequestedGc = rec.lastLowMemory;
4190                    }
4191                    rec.reportLowMemory = true;
4192                    rec.lastLowMemory = now;
4193                    mProcessesToGc.remove(rec);
4194                    addProcessToGcListLocked(rec);
4195                }
4196            }
4197            if (doReport) {
4198                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4199                mHandler.sendMessage(msg);
4200            }
4201            scheduleAppGcsLocked();
4202        }
4203    }
4204
4205    final void appDiedLocked(ProcessRecord app, int pid,
4206            IApplicationThread thread) {
4207
4208        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4209        synchronized (stats) {
4210            stats.noteProcessDiedLocked(app.info.uid, pid);
4211        }
4212
4213        Process.killProcessGroup(app.info.uid, pid);
4214
4215        // Clean up already done if the process has been re-started.
4216        if (app.pid == pid && app.thread != null &&
4217                app.thread.asBinder() == thread.asBinder()) {
4218            boolean doLowMem = app.instrumentationClass == null;
4219            boolean doOomAdj = doLowMem;
4220            if (!app.killedByAm) {
4221                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4222                        + ") has died.");
4223                mAllowLowerMemLevel = true;
4224            } else {
4225                // Note that we always want to do oom adj to update our state with the
4226                // new number of procs.
4227                mAllowLowerMemLevel = false;
4228                doLowMem = false;
4229            }
4230            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4231            if (DEBUG_CLEANUP) Slog.v(
4232                TAG, "Dying app: " + app + ", pid: " + pid
4233                + ", thread: " + thread.asBinder());
4234            handleAppDiedLocked(app, false, true);
4235
4236            if (doOomAdj) {
4237                updateOomAdjLocked();
4238            }
4239            if (doLowMem) {
4240                doLowMemReportIfNeededLocked(app);
4241            }
4242        } else if (app.pid != pid) {
4243            // A new process has already been started.
4244            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4245                    + ") has died and restarted (pid " + app.pid + ").");
4246            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4247        } else if (DEBUG_PROCESSES) {
4248            Slog.d(TAG, "Received spurious death notification for thread "
4249                    + thread.asBinder());
4250        }
4251    }
4252
4253    /**
4254     * If a stack trace dump file is configured, dump process stack traces.
4255     * @param clearTraces causes the dump file to be erased prior to the new
4256     *    traces being written, if true; when false, the new traces will be
4257     *    appended to any existing file content.
4258     * @param firstPids of dalvik VM processes to dump stack traces for first
4259     * @param lastPids of dalvik VM processes to dump stack traces for last
4260     * @param nativeProcs optional list of native process names to dump stack crawls
4261     * @return file containing stack traces, or null if no dump file is configured
4262     */
4263    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4264            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4265        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4266        if (tracesPath == null || tracesPath.length() == 0) {
4267            return null;
4268        }
4269
4270        File tracesFile = new File(tracesPath);
4271        try {
4272            File tracesDir = tracesFile.getParentFile();
4273            if (!tracesDir.exists()) {
4274                tracesFile.mkdirs();
4275                if (!SELinux.restorecon(tracesDir)) {
4276                    return null;
4277                }
4278            }
4279            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4280
4281            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4282            tracesFile.createNewFile();
4283            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4284        } catch (IOException e) {
4285            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4286            return null;
4287        }
4288
4289        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4290        return tracesFile;
4291    }
4292
4293    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4294            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4295        // Use a FileObserver to detect when traces finish writing.
4296        // The order of traces is considered important to maintain for legibility.
4297        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4298            @Override
4299            public synchronized void onEvent(int event, String path) { notify(); }
4300        };
4301
4302        try {
4303            observer.startWatching();
4304
4305            // First collect all of the stacks of the most important pids.
4306            if (firstPids != null) {
4307                try {
4308                    int num = firstPids.size();
4309                    for (int i = 0; i < num; i++) {
4310                        synchronized (observer) {
4311                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4312                            observer.wait(200);  // Wait for write-close, give up after 200msec
4313                        }
4314                    }
4315                } catch (InterruptedException e) {
4316                    Log.wtf(TAG, e);
4317                }
4318            }
4319
4320            // Next collect the stacks of the native pids
4321            if (nativeProcs != null) {
4322                int[] pids = Process.getPidsForCommands(nativeProcs);
4323                if (pids != null) {
4324                    for (int pid : pids) {
4325                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4326                    }
4327                }
4328            }
4329
4330            // Lastly, measure CPU usage.
4331            if (processCpuTracker != null) {
4332                processCpuTracker.init();
4333                System.gc();
4334                processCpuTracker.update();
4335                try {
4336                    synchronized (processCpuTracker) {
4337                        processCpuTracker.wait(500); // measure over 1/2 second.
4338                    }
4339                } catch (InterruptedException e) {
4340                }
4341                processCpuTracker.update();
4342
4343                // We'll take the stack crawls of just the top apps using CPU.
4344                final int N = processCpuTracker.countWorkingStats();
4345                int numProcs = 0;
4346                for (int i=0; i<N && numProcs<5; i++) {
4347                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4348                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4349                        numProcs++;
4350                        try {
4351                            synchronized (observer) {
4352                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4353                                observer.wait(200);  // Wait for write-close, give up after 200msec
4354                            }
4355                        } catch (InterruptedException e) {
4356                            Log.wtf(TAG, e);
4357                        }
4358
4359                    }
4360                }
4361            }
4362        } finally {
4363            observer.stopWatching();
4364        }
4365    }
4366
4367    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4368        if (true || IS_USER_BUILD) {
4369            return;
4370        }
4371        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4372        if (tracesPath == null || tracesPath.length() == 0) {
4373            return;
4374        }
4375
4376        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4377        StrictMode.allowThreadDiskWrites();
4378        try {
4379            final File tracesFile = new File(tracesPath);
4380            final File tracesDir = tracesFile.getParentFile();
4381            final File tracesTmp = new File(tracesDir, "__tmp__");
4382            try {
4383                if (!tracesDir.exists()) {
4384                    tracesFile.mkdirs();
4385                    if (!SELinux.restorecon(tracesDir.getPath())) {
4386                        return;
4387                    }
4388                }
4389                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4390
4391                if (tracesFile.exists()) {
4392                    tracesTmp.delete();
4393                    tracesFile.renameTo(tracesTmp);
4394                }
4395                StringBuilder sb = new StringBuilder();
4396                Time tobj = new Time();
4397                tobj.set(System.currentTimeMillis());
4398                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4399                sb.append(": ");
4400                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4401                sb.append(" since ");
4402                sb.append(msg);
4403                FileOutputStream fos = new FileOutputStream(tracesFile);
4404                fos.write(sb.toString().getBytes());
4405                if (app == null) {
4406                    fos.write("\n*** No application process!".getBytes());
4407                }
4408                fos.close();
4409                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4410            } catch (IOException e) {
4411                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4412                return;
4413            }
4414
4415            if (app != null) {
4416                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4417                firstPids.add(app.pid);
4418                dumpStackTraces(tracesPath, firstPids, null, null, null);
4419            }
4420
4421            File lastTracesFile = null;
4422            File curTracesFile = null;
4423            for (int i=9; i>=0; i--) {
4424                String name = String.format(Locale.US, "slow%02d.txt", i);
4425                curTracesFile = new File(tracesDir, name);
4426                if (curTracesFile.exists()) {
4427                    if (lastTracesFile != null) {
4428                        curTracesFile.renameTo(lastTracesFile);
4429                    } else {
4430                        curTracesFile.delete();
4431                    }
4432                }
4433                lastTracesFile = curTracesFile;
4434            }
4435            tracesFile.renameTo(curTracesFile);
4436            if (tracesTmp.exists()) {
4437                tracesTmp.renameTo(tracesFile);
4438            }
4439        } finally {
4440            StrictMode.setThreadPolicy(oldPolicy);
4441        }
4442    }
4443
4444    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4445            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4446        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4447        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4448
4449        if (mController != null) {
4450            try {
4451                // 0 == continue, -1 = kill process immediately
4452                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4453                if (res < 0 && app.pid != MY_PID) {
4454                    Process.killProcess(app.pid);
4455                    Process.killProcessGroup(app.info.uid, app.pid);
4456                }
4457            } catch (RemoteException e) {
4458                mController = null;
4459                Watchdog.getInstance().setActivityController(null);
4460            }
4461        }
4462
4463        long anrTime = SystemClock.uptimeMillis();
4464        if (MONITOR_CPU_USAGE) {
4465            updateCpuStatsNow();
4466        }
4467
4468        synchronized (this) {
4469            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4470            if (mShuttingDown) {
4471                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4472                return;
4473            } else if (app.notResponding) {
4474                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4475                return;
4476            } else if (app.crashing) {
4477                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4478                return;
4479            }
4480
4481            // In case we come through here for the same app before completing
4482            // this one, mark as anring now so we will bail out.
4483            app.notResponding = true;
4484
4485            // Log the ANR to the event log.
4486            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4487                    app.processName, app.info.flags, annotation);
4488
4489            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4490            firstPids.add(app.pid);
4491
4492            int parentPid = app.pid;
4493            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4494            if (parentPid != app.pid) firstPids.add(parentPid);
4495
4496            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4497
4498            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4499                ProcessRecord r = mLruProcesses.get(i);
4500                if (r != null && r.thread != null) {
4501                    int pid = r.pid;
4502                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4503                        if (r.persistent) {
4504                            firstPids.add(pid);
4505                        } else {
4506                            lastPids.put(pid, Boolean.TRUE);
4507                        }
4508                    }
4509                }
4510            }
4511        }
4512
4513        // Log the ANR to the main log.
4514        StringBuilder info = new StringBuilder();
4515        info.setLength(0);
4516        info.append("ANR in ").append(app.processName);
4517        if (activity != null && activity.shortComponentName != null) {
4518            info.append(" (").append(activity.shortComponentName).append(")");
4519        }
4520        info.append("\n");
4521        info.append("PID: ").append(app.pid).append("\n");
4522        if (annotation != null) {
4523            info.append("Reason: ").append(annotation).append("\n");
4524        }
4525        if (parent != null && parent != activity) {
4526            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4527        }
4528
4529        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4530
4531        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4532                NATIVE_STACKS_OF_INTEREST);
4533
4534        String cpuInfo = null;
4535        if (MONITOR_CPU_USAGE) {
4536            updateCpuStatsNow();
4537            synchronized (mProcessCpuThread) {
4538                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4539            }
4540            info.append(processCpuTracker.printCurrentLoad());
4541            info.append(cpuInfo);
4542        }
4543
4544        info.append(processCpuTracker.printCurrentState(anrTime));
4545
4546        Slog.e(TAG, info.toString());
4547        if (tracesFile == null) {
4548            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4549            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4550        }
4551
4552        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4553                cpuInfo, tracesFile, null);
4554
4555        if (mController != null) {
4556            try {
4557                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4558                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4559                if (res != 0) {
4560                    if (res < 0 && app.pid != MY_PID) {
4561                        Process.killProcess(app.pid);
4562                        Process.killProcessGroup(app.info.uid, app.pid);
4563                    } else {
4564                        synchronized (this) {
4565                            mServices.scheduleServiceTimeoutLocked(app);
4566                        }
4567                    }
4568                    return;
4569                }
4570            } catch (RemoteException e) {
4571                mController = null;
4572                Watchdog.getInstance().setActivityController(null);
4573            }
4574        }
4575
4576        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4577        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4578                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4579
4580        synchronized (this) {
4581            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4582                killUnneededProcessLocked(app, "background ANR");
4583                return;
4584            }
4585
4586            // Set the app's notResponding state, and look up the errorReportReceiver
4587            makeAppNotRespondingLocked(app,
4588                    activity != null ? activity.shortComponentName : null,
4589                    annotation != null ? "ANR " + annotation : "ANR",
4590                    info.toString());
4591
4592            // Bring up the infamous App Not Responding dialog
4593            Message msg = Message.obtain();
4594            HashMap<String, Object> map = new HashMap<String, Object>();
4595            msg.what = SHOW_NOT_RESPONDING_MSG;
4596            msg.obj = map;
4597            msg.arg1 = aboveSystem ? 1 : 0;
4598            map.put("app", app);
4599            if (activity != null) {
4600                map.put("activity", activity);
4601            }
4602
4603            mHandler.sendMessage(msg);
4604        }
4605    }
4606
4607    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4608        if (!mLaunchWarningShown) {
4609            mLaunchWarningShown = true;
4610            mHandler.post(new Runnable() {
4611                @Override
4612                public void run() {
4613                    synchronized (ActivityManagerService.this) {
4614                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4615                        d.show();
4616                        mHandler.postDelayed(new Runnable() {
4617                            @Override
4618                            public void run() {
4619                                synchronized (ActivityManagerService.this) {
4620                                    d.dismiss();
4621                                    mLaunchWarningShown = false;
4622                                }
4623                            }
4624                        }, 4000);
4625                    }
4626                }
4627            });
4628        }
4629    }
4630
4631    @Override
4632    public boolean clearApplicationUserData(final String packageName,
4633            final IPackageDataObserver observer, int userId) {
4634        enforceNotIsolatedCaller("clearApplicationUserData");
4635        int uid = Binder.getCallingUid();
4636        int pid = Binder.getCallingPid();
4637        userId = handleIncomingUser(pid, uid,
4638                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4639        long callingId = Binder.clearCallingIdentity();
4640        try {
4641            IPackageManager pm = AppGlobals.getPackageManager();
4642            int pkgUid = -1;
4643            synchronized(this) {
4644                try {
4645                    pkgUid = pm.getPackageUid(packageName, userId);
4646                } catch (RemoteException e) {
4647                }
4648                if (pkgUid == -1) {
4649                    Slog.w(TAG, "Invalid packageName: " + packageName);
4650                    if (observer != null) {
4651                        try {
4652                            observer.onRemoveCompleted(packageName, false);
4653                        } catch (RemoteException e) {
4654                            Slog.i(TAG, "Observer no longer exists.");
4655                        }
4656                    }
4657                    return false;
4658                }
4659                if (uid == pkgUid || checkComponentPermission(
4660                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4661                        pid, uid, -1, true)
4662                        == PackageManager.PERMISSION_GRANTED) {
4663                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4664                } else {
4665                    throw new SecurityException("PID " + pid + " does not have permission "
4666                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4667                                    + " of package " + packageName);
4668                }
4669            }
4670
4671            try {
4672                // Clear application user data
4673                pm.clearApplicationUserData(packageName, observer, userId);
4674
4675                // Remove all permissions granted from/to this package
4676                removeUriPermissionsForPackageLocked(packageName, userId, true);
4677
4678                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4679                        Uri.fromParts("package", packageName, null));
4680                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4681                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4682                        null, null, 0, null, null, null, false, false, userId);
4683            } catch (RemoteException e) {
4684            }
4685        } finally {
4686            Binder.restoreCallingIdentity(callingId);
4687        }
4688        return true;
4689    }
4690
4691    @Override
4692    public void killBackgroundProcesses(final String packageName, int userId) {
4693        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4694                != PackageManager.PERMISSION_GRANTED &&
4695                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4696                        != PackageManager.PERMISSION_GRANTED) {
4697            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4698                    + Binder.getCallingPid()
4699                    + ", uid=" + Binder.getCallingUid()
4700                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4701            Slog.w(TAG, msg);
4702            throw new SecurityException(msg);
4703        }
4704
4705        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4706                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4707        long callingId = Binder.clearCallingIdentity();
4708        try {
4709            IPackageManager pm = AppGlobals.getPackageManager();
4710            synchronized(this) {
4711                int appId = -1;
4712                try {
4713                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4714                } catch (RemoteException e) {
4715                }
4716                if (appId == -1) {
4717                    Slog.w(TAG, "Invalid packageName: " + packageName);
4718                    return;
4719                }
4720                killPackageProcessesLocked(packageName, appId, userId,
4721                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4722            }
4723        } finally {
4724            Binder.restoreCallingIdentity(callingId);
4725        }
4726    }
4727
4728    @Override
4729    public void killAllBackgroundProcesses() {
4730        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4731                != PackageManager.PERMISSION_GRANTED) {
4732            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4733                    + Binder.getCallingPid()
4734                    + ", uid=" + Binder.getCallingUid()
4735                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4736            Slog.w(TAG, msg);
4737            throw new SecurityException(msg);
4738        }
4739
4740        long callingId = Binder.clearCallingIdentity();
4741        try {
4742            synchronized(this) {
4743                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4744                final int NP = mProcessNames.getMap().size();
4745                for (int ip=0; ip<NP; ip++) {
4746                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4747                    final int NA = apps.size();
4748                    for (int ia=0; ia<NA; ia++) {
4749                        ProcessRecord app = apps.valueAt(ia);
4750                        if (app.persistent) {
4751                            // we don't kill persistent processes
4752                            continue;
4753                        }
4754                        if (app.removed) {
4755                            procs.add(app);
4756                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4757                            app.removed = true;
4758                            procs.add(app);
4759                        }
4760                    }
4761                }
4762
4763                int N = procs.size();
4764                for (int i=0; i<N; i++) {
4765                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4766                }
4767                mAllowLowerMemLevel = true;
4768                updateOomAdjLocked();
4769                doLowMemReportIfNeededLocked(null);
4770            }
4771        } finally {
4772            Binder.restoreCallingIdentity(callingId);
4773        }
4774    }
4775
4776    @Override
4777    public void forceStopPackage(final String packageName, int userId) {
4778        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4779                != PackageManager.PERMISSION_GRANTED) {
4780            String msg = "Permission Denial: forceStopPackage() from pid="
4781                    + Binder.getCallingPid()
4782                    + ", uid=" + Binder.getCallingUid()
4783                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4784            Slog.w(TAG, msg);
4785            throw new SecurityException(msg);
4786        }
4787        final int callingPid = Binder.getCallingPid();
4788        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4789                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4790        long callingId = Binder.clearCallingIdentity();
4791        try {
4792            IPackageManager pm = AppGlobals.getPackageManager();
4793            synchronized(this) {
4794                int[] users = userId == UserHandle.USER_ALL
4795                        ? getUsersLocked() : new int[] { userId };
4796                for (int user : users) {
4797                    int pkgUid = -1;
4798                    try {
4799                        pkgUid = pm.getPackageUid(packageName, user);
4800                    } catch (RemoteException e) {
4801                    }
4802                    if (pkgUid == -1) {
4803                        Slog.w(TAG, "Invalid packageName: " + packageName);
4804                        continue;
4805                    }
4806                    try {
4807                        pm.setPackageStoppedState(packageName, true, user);
4808                    } catch (RemoteException e) {
4809                    } catch (IllegalArgumentException e) {
4810                        Slog.w(TAG, "Failed trying to unstop package "
4811                                + packageName + ": " + e);
4812                    }
4813                    if (isUserRunningLocked(user, false)) {
4814                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4815                    }
4816                }
4817            }
4818        } finally {
4819            Binder.restoreCallingIdentity(callingId);
4820        }
4821    }
4822
4823    @Override
4824    public void addPackageDependency(String packageName) {
4825        synchronized (this) {
4826            int callingPid = Binder.getCallingPid();
4827            if (callingPid == Process.myPid()) {
4828                //  Yeah, um, no.
4829                Slog.w(TAG, "Can't addPackageDependency on system process");
4830                return;
4831            }
4832            ProcessRecord proc;
4833            synchronized (mPidsSelfLocked) {
4834                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4835            }
4836            if (proc != null) {
4837                if (proc.pkgDeps == null) {
4838                    proc.pkgDeps = new ArraySet<String>(1);
4839                }
4840                proc.pkgDeps.add(packageName);
4841            }
4842        }
4843    }
4844
4845    /*
4846     * The pkg name and app id have to be specified.
4847     */
4848    @Override
4849    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4850        if (pkg == null) {
4851            return;
4852        }
4853        // Make sure the uid is valid.
4854        if (appid < 0) {
4855            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4856            return;
4857        }
4858        int callerUid = Binder.getCallingUid();
4859        // Only the system server can kill an application
4860        if (callerUid == Process.SYSTEM_UID) {
4861            // Post an aysnc message to kill the application
4862            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4863            msg.arg1 = appid;
4864            msg.arg2 = 0;
4865            Bundle bundle = new Bundle();
4866            bundle.putString("pkg", pkg);
4867            bundle.putString("reason", reason);
4868            msg.obj = bundle;
4869            mHandler.sendMessage(msg);
4870        } else {
4871            throw new SecurityException(callerUid + " cannot kill pkg: " +
4872                    pkg);
4873        }
4874    }
4875
4876    @Override
4877    public void closeSystemDialogs(String reason) {
4878        enforceNotIsolatedCaller("closeSystemDialogs");
4879
4880        final int pid = Binder.getCallingPid();
4881        final int uid = Binder.getCallingUid();
4882        final long origId = Binder.clearCallingIdentity();
4883        try {
4884            synchronized (this) {
4885                // Only allow this from foreground processes, so that background
4886                // applications can't abuse it to prevent system UI from being shown.
4887                if (uid >= Process.FIRST_APPLICATION_UID) {
4888                    ProcessRecord proc;
4889                    synchronized (mPidsSelfLocked) {
4890                        proc = mPidsSelfLocked.get(pid);
4891                    }
4892                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4893                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4894                                + " from background process " + proc);
4895                        return;
4896                    }
4897                }
4898                closeSystemDialogsLocked(reason);
4899            }
4900        } finally {
4901            Binder.restoreCallingIdentity(origId);
4902        }
4903    }
4904
4905    void closeSystemDialogsLocked(String reason) {
4906        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4907        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4908                | Intent.FLAG_RECEIVER_FOREGROUND);
4909        if (reason != null) {
4910            intent.putExtra("reason", reason);
4911        }
4912        mWindowManager.closeSystemDialogs(reason);
4913
4914        mStackSupervisor.closeSystemDialogsLocked();
4915
4916        broadcastIntentLocked(null, null, intent, null,
4917                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4918                Process.SYSTEM_UID, UserHandle.USER_ALL);
4919    }
4920
4921    @Override
4922    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4923        enforceNotIsolatedCaller("getProcessMemoryInfo");
4924        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4925        for (int i=pids.length-1; i>=0; i--) {
4926            ProcessRecord proc;
4927            int oomAdj;
4928            synchronized (this) {
4929                synchronized (mPidsSelfLocked) {
4930                    proc = mPidsSelfLocked.get(pids[i]);
4931                    oomAdj = proc != null ? proc.setAdj : 0;
4932                }
4933            }
4934            infos[i] = new Debug.MemoryInfo();
4935            Debug.getMemoryInfo(pids[i], infos[i]);
4936            if (proc != null) {
4937                synchronized (this) {
4938                    if (proc.thread != null && proc.setAdj == oomAdj) {
4939                        // Record this for posterity if the process has been stable.
4940                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4941                                infos[i].getTotalUss(), false, proc.pkgList);
4942                    }
4943                }
4944            }
4945        }
4946        return infos;
4947    }
4948
4949    @Override
4950    public long[] getProcessPss(int[] pids) {
4951        enforceNotIsolatedCaller("getProcessPss");
4952        long[] pss = new long[pids.length];
4953        for (int i=pids.length-1; i>=0; i--) {
4954            ProcessRecord proc;
4955            int oomAdj;
4956            synchronized (this) {
4957                synchronized (mPidsSelfLocked) {
4958                    proc = mPidsSelfLocked.get(pids[i]);
4959                    oomAdj = proc != null ? proc.setAdj : 0;
4960                }
4961            }
4962            long[] tmpUss = new long[1];
4963            pss[i] = Debug.getPss(pids[i], tmpUss);
4964            if (proc != null) {
4965                synchronized (this) {
4966                    if (proc.thread != null && proc.setAdj == oomAdj) {
4967                        // Record this for posterity if the process has been stable.
4968                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4969                    }
4970                }
4971            }
4972        }
4973        return pss;
4974    }
4975
4976    @Override
4977    public void killApplicationProcess(String processName, int uid) {
4978        if (processName == null) {
4979            return;
4980        }
4981
4982        int callerUid = Binder.getCallingUid();
4983        // Only the system server can kill an application
4984        if (callerUid == Process.SYSTEM_UID) {
4985            synchronized (this) {
4986                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4987                if (app != null && app.thread != null) {
4988                    try {
4989                        app.thread.scheduleSuicide();
4990                    } catch (RemoteException e) {
4991                        // If the other end already died, then our work here is done.
4992                    }
4993                } else {
4994                    Slog.w(TAG, "Process/uid not found attempting kill of "
4995                            + processName + " / " + uid);
4996                }
4997            }
4998        } else {
4999            throw new SecurityException(callerUid + " cannot kill app process: " +
5000                    processName);
5001        }
5002    }
5003
5004    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5005        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5006                false, true, false, false, UserHandle.getUserId(uid), reason);
5007        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5008                Uri.fromParts("package", packageName, null));
5009        if (!mProcessesReady) {
5010            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5011                    | Intent.FLAG_RECEIVER_FOREGROUND);
5012        }
5013        intent.putExtra(Intent.EXTRA_UID, uid);
5014        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5015        broadcastIntentLocked(null, null, intent,
5016                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5017                false, false,
5018                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5019    }
5020
5021    private void forceStopUserLocked(int userId, String reason) {
5022        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5023        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5024        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5025                | Intent.FLAG_RECEIVER_FOREGROUND);
5026        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5027        broadcastIntentLocked(null, null, intent,
5028                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5029                false, false,
5030                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5031    }
5032
5033    private final boolean killPackageProcessesLocked(String packageName, int appId,
5034            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5035            boolean doit, boolean evenPersistent, String reason) {
5036        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5037
5038        // Remove all processes this package may have touched: all with the
5039        // same UID (except for the system or root user), and all whose name
5040        // matches the package name.
5041        final int NP = mProcessNames.getMap().size();
5042        for (int ip=0; ip<NP; ip++) {
5043            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5044            final int NA = apps.size();
5045            for (int ia=0; ia<NA; ia++) {
5046                ProcessRecord app = apps.valueAt(ia);
5047                if (app.persistent && !evenPersistent) {
5048                    // we don't kill persistent processes
5049                    continue;
5050                }
5051                if (app.removed) {
5052                    if (doit) {
5053                        procs.add(app);
5054                    }
5055                    continue;
5056                }
5057
5058                // Skip process if it doesn't meet our oom adj requirement.
5059                if (app.setAdj < minOomAdj) {
5060                    continue;
5061                }
5062
5063                // If no package is specified, we call all processes under the
5064                // give user id.
5065                if (packageName == null) {
5066                    if (app.userId != userId) {
5067                        continue;
5068                    }
5069                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5070                        continue;
5071                    }
5072                // Package has been specified, we want to hit all processes
5073                // that match it.  We need to qualify this by the processes
5074                // that are running under the specified app and user ID.
5075                } else {
5076                    final boolean isDep = app.pkgDeps != null
5077                            && app.pkgDeps.contains(packageName);
5078                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5079                        continue;
5080                    }
5081                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5082                        continue;
5083                    }
5084                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5085                        continue;
5086                    }
5087                }
5088
5089                // Process has passed all conditions, kill it!
5090                if (!doit) {
5091                    return true;
5092                }
5093                app.removed = true;
5094                procs.add(app);
5095            }
5096        }
5097
5098        int N = procs.size();
5099        for (int i=0; i<N; i++) {
5100            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5101        }
5102        updateOomAdjLocked();
5103        return N > 0;
5104    }
5105
5106    private final boolean forceStopPackageLocked(String name, int appId,
5107            boolean callerWillRestart, boolean purgeCache, boolean doit,
5108            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5109        int i;
5110        int N;
5111
5112        if (userId == UserHandle.USER_ALL && name == null) {
5113            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5114        }
5115
5116        if (appId < 0 && name != null) {
5117            try {
5118                appId = UserHandle.getAppId(
5119                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5120            } catch (RemoteException e) {
5121            }
5122        }
5123
5124        if (doit) {
5125            if (name != null) {
5126                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5127                        + " user=" + userId + ": " + reason);
5128            } else {
5129                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5130            }
5131
5132            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5133            for (int ip=pmap.size()-1; ip>=0; ip--) {
5134                SparseArray<Long> ba = pmap.valueAt(ip);
5135                for (i=ba.size()-1; i>=0; i--) {
5136                    boolean remove = false;
5137                    final int entUid = ba.keyAt(i);
5138                    if (name != null) {
5139                        if (userId == UserHandle.USER_ALL) {
5140                            if (UserHandle.getAppId(entUid) == appId) {
5141                                remove = true;
5142                            }
5143                        } else {
5144                            if (entUid == UserHandle.getUid(userId, appId)) {
5145                                remove = true;
5146                            }
5147                        }
5148                    } else if (UserHandle.getUserId(entUid) == userId) {
5149                        remove = true;
5150                    }
5151                    if (remove) {
5152                        ba.removeAt(i);
5153                    }
5154                }
5155                if (ba.size() == 0) {
5156                    pmap.removeAt(ip);
5157                }
5158            }
5159        }
5160
5161        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5162                -100, callerWillRestart, true, doit, evenPersistent,
5163                name == null ? ("stop user " + userId) : ("stop " + name));
5164
5165        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5166            if (!doit) {
5167                return true;
5168            }
5169            didSomething = true;
5170        }
5171
5172        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5173            if (!doit) {
5174                return true;
5175            }
5176            didSomething = true;
5177        }
5178
5179        if (name == null) {
5180            // Remove all sticky broadcasts from this user.
5181            mStickyBroadcasts.remove(userId);
5182        }
5183
5184        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5185        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5186                userId, providers)) {
5187            if (!doit) {
5188                return true;
5189            }
5190            didSomething = true;
5191        }
5192        N = providers.size();
5193        for (i=0; i<N; i++) {
5194            removeDyingProviderLocked(null, providers.get(i), true);
5195        }
5196
5197        // Remove transient permissions granted from/to this package/user
5198        removeUriPermissionsForPackageLocked(name, userId, false);
5199
5200        if (name == null || uninstalling) {
5201            // Remove pending intents.  For now we only do this when force
5202            // stopping users, because we have some problems when doing this
5203            // for packages -- app widgets are not currently cleaned up for
5204            // such packages, so they can be left with bad pending intents.
5205            if (mIntentSenderRecords.size() > 0) {
5206                Iterator<WeakReference<PendingIntentRecord>> it
5207                        = mIntentSenderRecords.values().iterator();
5208                while (it.hasNext()) {
5209                    WeakReference<PendingIntentRecord> wpir = it.next();
5210                    if (wpir == null) {
5211                        it.remove();
5212                        continue;
5213                    }
5214                    PendingIntentRecord pir = wpir.get();
5215                    if (pir == null) {
5216                        it.remove();
5217                        continue;
5218                    }
5219                    if (name == null) {
5220                        // Stopping user, remove all objects for the user.
5221                        if (pir.key.userId != userId) {
5222                            // Not the same user, skip it.
5223                            continue;
5224                        }
5225                    } else {
5226                        if (UserHandle.getAppId(pir.uid) != appId) {
5227                            // Different app id, skip it.
5228                            continue;
5229                        }
5230                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5231                            // Different user, skip it.
5232                            continue;
5233                        }
5234                        if (!pir.key.packageName.equals(name)) {
5235                            // Different package, skip it.
5236                            continue;
5237                        }
5238                    }
5239                    if (!doit) {
5240                        return true;
5241                    }
5242                    didSomething = true;
5243                    it.remove();
5244                    pir.canceled = true;
5245                    if (pir.key.activity != null) {
5246                        pir.key.activity.pendingResults.remove(pir.ref);
5247                    }
5248                }
5249            }
5250        }
5251
5252        if (doit) {
5253            if (purgeCache && name != null) {
5254                AttributeCache ac = AttributeCache.instance();
5255                if (ac != null) {
5256                    ac.removePackage(name);
5257                }
5258            }
5259            if (mBooted) {
5260                mStackSupervisor.resumeTopActivitiesLocked();
5261                mStackSupervisor.scheduleIdleLocked();
5262            }
5263        }
5264
5265        return didSomething;
5266    }
5267
5268    private final boolean removeProcessLocked(ProcessRecord app,
5269            boolean callerWillRestart, boolean allowRestart, String reason) {
5270        final String name = app.processName;
5271        final int uid = app.uid;
5272        if (DEBUG_PROCESSES) Slog.d(
5273            TAG, "Force removing proc " + app.toShortString() + " (" + name
5274            + "/" + uid + ")");
5275
5276        mProcessNames.remove(name, uid);
5277        mIsolatedProcesses.remove(app.uid);
5278        if (mHeavyWeightProcess == app) {
5279            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5280                    mHeavyWeightProcess.userId, 0));
5281            mHeavyWeightProcess = null;
5282        }
5283        boolean needRestart = false;
5284        if (app.pid > 0 && app.pid != MY_PID) {
5285            int pid = app.pid;
5286            synchronized (mPidsSelfLocked) {
5287                mPidsSelfLocked.remove(pid);
5288                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5289            }
5290            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5291            if (app.isolated) {
5292                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5293            }
5294            killUnneededProcessLocked(app, reason);
5295            Process.killProcessGroup(app.info.uid, app.pid);
5296            handleAppDiedLocked(app, true, allowRestart);
5297            removeLruProcessLocked(app);
5298
5299            if (app.persistent && !app.isolated) {
5300                if (!callerWillRestart) {
5301                    addAppLocked(app.info, false, null /* ABI override */);
5302                } else {
5303                    needRestart = true;
5304                }
5305            }
5306        } else {
5307            mRemovedProcesses.add(app);
5308        }
5309
5310        return needRestart;
5311    }
5312
5313    private final void processStartTimedOutLocked(ProcessRecord app) {
5314        final int pid = app.pid;
5315        boolean gone = false;
5316        synchronized (mPidsSelfLocked) {
5317            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5318            if (knownApp != null && knownApp.thread == null) {
5319                mPidsSelfLocked.remove(pid);
5320                gone = true;
5321            }
5322        }
5323
5324        if (gone) {
5325            Slog.w(TAG, "Process " + app + " failed to attach");
5326            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5327                    pid, app.uid, app.processName);
5328            mProcessNames.remove(app.processName, app.uid);
5329            mIsolatedProcesses.remove(app.uid);
5330            if (mHeavyWeightProcess == app) {
5331                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5332                        mHeavyWeightProcess.userId, 0));
5333                mHeavyWeightProcess = null;
5334            }
5335            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5336            if (app.isolated) {
5337                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5338            }
5339            // Take care of any launching providers waiting for this process.
5340            checkAppInLaunchingProvidersLocked(app, true);
5341            // Take care of any services that are waiting for the process.
5342            mServices.processStartTimedOutLocked(app);
5343            killUnneededProcessLocked(app, "start timeout");
5344            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5345                Slog.w(TAG, "Unattached app died before backup, skipping");
5346                try {
5347                    IBackupManager bm = IBackupManager.Stub.asInterface(
5348                            ServiceManager.getService(Context.BACKUP_SERVICE));
5349                    bm.agentDisconnected(app.info.packageName);
5350                } catch (RemoteException e) {
5351                    // Can't happen; the backup manager is local
5352                }
5353            }
5354            if (isPendingBroadcastProcessLocked(pid)) {
5355                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5356                skipPendingBroadcastLocked(pid);
5357            }
5358        } else {
5359            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5360        }
5361    }
5362
5363    private final boolean attachApplicationLocked(IApplicationThread thread,
5364            int pid) {
5365
5366        // Find the application record that is being attached...  either via
5367        // the pid if we are running in multiple processes, or just pull the
5368        // next app record if we are emulating process with anonymous threads.
5369        ProcessRecord app;
5370        if (pid != MY_PID && pid >= 0) {
5371            synchronized (mPidsSelfLocked) {
5372                app = mPidsSelfLocked.get(pid);
5373            }
5374        } else {
5375            app = null;
5376        }
5377
5378        if (app == null) {
5379            Slog.w(TAG, "No pending application record for pid " + pid
5380                    + " (IApplicationThread " + thread + "); dropping process");
5381            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5382            if (pid > 0 && pid != MY_PID) {
5383                Process.killProcessQuiet(pid);
5384                //TODO: Process.killProcessGroup(app.info.uid, pid);
5385            } else {
5386                try {
5387                    thread.scheduleExit();
5388                } catch (Exception e) {
5389                    // Ignore exceptions.
5390                }
5391            }
5392            return false;
5393        }
5394
5395        // If this application record is still attached to a previous
5396        // process, clean it up now.
5397        if (app.thread != null) {
5398            handleAppDiedLocked(app, true, true);
5399        }
5400
5401        // Tell the process all about itself.
5402
5403        if (localLOGV) Slog.v(
5404                TAG, "Binding process pid " + pid + " to record " + app);
5405
5406        final String processName = app.processName;
5407        try {
5408            AppDeathRecipient adr = new AppDeathRecipient(
5409                    app, pid, thread);
5410            thread.asBinder().linkToDeath(adr, 0);
5411            app.deathRecipient = adr;
5412        } catch (RemoteException e) {
5413            app.resetPackageList(mProcessStats);
5414            startProcessLocked(app, "link fail", processName);
5415            return false;
5416        }
5417
5418        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5419
5420        app.makeActive(thread, mProcessStats);
5421        app.curAdj = app.setAdj = -100;
5422        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5423        app.forcingToForeground = null;
5424        updateProcessForegroundLocked(app, false, false);
5425        app.hasShownUi = false;
5426        app.debugging = false;
5427        app.cached = false;
5428
5429        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5430
5431        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5432        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5433
5434        if (!normalMode) {
5435            Slog.i(TAG, "Launching preboot mode app: " + app);
5436        }
5437
5438        if (localLOGV) Slog.v(
5439            TAG, "New app record " + app
5440            + " thread=" + thread.asBinder() + " pid=" + pid);
5441        try {
5442            int testMode = IApplicationThread.DEBUG_OFF;
5443            if (mDebugApp != null && mDebugApp.equals(processName)) {
5444                testMode = mWaitForDebugger
5445                    ? IApplicationThread.DEBUG_WAIT
5446                    : IApplicationThread.DEBUG_ON;
5447                app.debugging = true;
5448                if (mDebugTransient) {
5449                    mDebugApp = mOrigDebugApp;
5450                    mWaitForDebugger = mOrigWaitForDebugger;
5451                }
5452            }
5453            String profileFile = app.instrumentationProfileFile;
5454            ParcelFileDescriptor profileFd = null;
5455            boolean profileAutoStop = false;
5456            if (mProfileApp != null && mProfileApp.equals(processName)) {
5457                mProfileProc = app;
5458                profileFile = mProfileFile;
5459                profileFd = mProfileFd;
5460                profileAutoStop = mAutoStopProfiler;
5461            }
5462            boolean enableOpenGlTrace = false;
5463            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5464                enableOpenGlTrace = true;
5465                mOpenGlTraceApp = null;
5466            }
5467
5468            // If the app is being launched for restore or full backup, set it up specially
5469            boolean isRestrictedBackupMode = false;
5470            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5471                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5472                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5473                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5474            }
5475
5476            ensurePackageDexOpt(app.instrumentationInfo != null
5477                    ? app.instrumentationInfo.packageName
5478                    : app.info.packageName);
5479            if (app.instrumentationClass != null) {
5480                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5481            }
5482            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5483                    + processName + " with config " + mConfiguration);
5484            ApplicationInfo appInfo = app.instrumentationInfo != null
5485                    ? app.instrumentationInfo : app.info;
5486            app.compat = compatibilityInfoForPackageLocked(appInfo);
5487            if (profileFd != null) {
5488                profileFd = profileFd.dup();
5489            }
5490            thread.bindApplication(processName, appInfo, providers,
5491                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5492                    app.instrumentationArguments, app.instrumentationWatcher,
5493                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5494                    isRestrictedBackupMode || !normalMode, app.persistent,
5495                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5496                    mCoreSettingsObserver.getCoreSettingsLocked());
5497            updateLruProcessLocked(app, false, null);
5498            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5499        } catch (Exception e) {
5500            // todo: Yikes!  What should we do?  For now we will try to
5501            // start another process, but that could easily get us in
5502            // an infinite loop of restarting processes...
5503            Slog.w(TAG, "Exception thrown during bind!", e);
5504
5505            app.resetPackageList(mProcessStats);
5506            app.unlinkDeathRecipient();
5507            startProcessLocked(app, "bind fail", processName);
5508            return false;
5509        }
5510
5511        // Remove this record from the list of starting applications.
5512        mPersistentStartingProcesses.remove(app);
5513        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5514                "Attach application locked removing on hold: " + app);
5515        mProcessesOnHold.remove(app);
5516
5517        boolean badApp = false;
5518        boolean didSomething = false;
5519
5520        // See if the top visible activity is waiting to run in this process...
5521        if (normalMode) {
5522            try {
5523                if (mStackSupervisor.attachApplicationLocked(app)) {
5524                    didSomething = true;
5525                }
5526            } catch (Exception e) {
5527                badApp = true;
5528            }
5529        }
5530
5531        // Find any services that should be running in this process...
5532        if (!badApp) {
5533            try {
5534                didSomething |= mServices.attachApplicationLocked(app, processName);
5535            } catch (Exception e) {
5536                badApp = true;
5537            }
5538        }
5539
5540        // Check if a next-broadcast receiver is in this process...
5541        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5542            try {
5543                didSomething |= sendPendingBroadcastsLocked(app);
5544            } catch (Exception e) {
5545                // If the app died trying to launch the receiver we declare it 'bad'
5546                badApp = true;
5547            }
5548        }
5549
5550        // Check whether the next backup agent is in this process...
5551        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5552            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5553            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5554            try {
5555                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5556                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5557                        mBackupTarget.backupMode);
5558            } catch (Exception e) {
5559                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5560                e.printStackTrace();
5561            }
5562        }
5563
5564        if (badApp) {
5565            // todo: Also need to kill application to deal with all
5566            // kinds of exceptions.
5567            handleAppDiedLocked(app, false, true);
5568            return false;
5569        }
5570
5571        if (!didSomething) {
5572            updateOomAdjLocked();
5573        }
5574
5575        return true;
5576    }
5577
5578    @Override
5579    public final void attachApplication(IApplicationThread thread) {
5580        synchronized (this) {
5581            int callingPid = Binder.getCallingPid();
5582            final long origId = Binder.clearCallingIdentity();
5583            attachApplicationLocked(thread, callingPid);
5584            Binder.restoreCallingIdentity(origId);
5585        }
5586    }
5587
5588    @Override
5589    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5590        final long origId = Binder.clearCallingIdentity();
5591        synchronized (this) {
5592            ActivityStack stack = ActivityRecord.getStackLocked(token);
5593            if (stack != null) {
5594                ActivityRecord r =
5595                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5596                if (stopProfiling) {
5597                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5598                        try {
5599                            mProfileFd.close();
5600                        } catch (IOException e) {
5601                        }
5602                        clearProfilerLocked();
5603                    }
5604                }
5605            }
5606        }
5607        Binder.restoreCallingIdentity(origId);
5608    }
5609
5610    void postEnableScreenAfterBootLocked() {
5611        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5612    }
5613
5614    void enableScreenAfterBoot() {
5615        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5616                SystemClock.uptimeMillis());
5617        mWindowManager.enableScreenAfterBoot();
5618
5619        synchronized (this) {
5620            updateEventDispatchingLocked();
5621        }
5622    }
5623
5624    @Override
5625    public void showBootMessage(final CharSequence msg, final boolean always) {
5626        enforceNotIsolatedCaller("showBootMessage");
5627        mWindowManager.showBootMessage(msg, always);
5628    }
5629
5630    @Override
5631    public void dismissKeyguardOnNextActivity() {
5632        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5633        final long token = Binder.clearCallingIdentity();
5634        try {
5635            synchronized (this) {
5636                if (DEBUG_LOCKSCREEN) logLockScreen("");
5637                if (mLockScreenShown) {
5638                    mLockScreenShown = false;
5639                    comeOutOfSleepIfNeededLocked();
5640                }
5641                mStackSupervisor.setDismissKeyguard(true);
5642            }
5643        } finally {
5644            Binder.restoreCallingIdentity(token);
5645        }
5646    }
5647
5648    final void finishBooting() {
5649        // Register receivers to handle package update events
5650        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5651
5652        synchronized (this) {
5653            // Ensure that any processes we had put on hold are now started
5654            // up.
5655            final int NP = mProcessesOnHold.size();
5656            if (NP > 0) {
5657                ArrayList<ProcessRecord> procs =
5658                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5659                for (int ip=0; ip<NP; ip++) {
5660                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5661                            + procs.get(ip));
5662                    startProcessLocked(procs.get(ip), "on-hold", null);
5663                }
5664            }
5665
5666            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5667                // Start looking for apps that are abusing wake locks.
5668                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5669                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5670                // Tell anyone interested that we are done booting!
5671                SystemProperties.set("sys.boot_completed", "1");
5672                SystemProperties.set("dev.bootcomplete", "1");
5673                for (int i=0; i<mStartedUsers.size(); i++) {
5674                    UserStartedState uss = mStartedUsers.valueAt(i);
5675                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5676                        uss.mState = UserStartedState.STATE_RUNNING;
5677                        final int userId = mStartedUsers.keyAt(i);
5678                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5679                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5680                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5681                        broadcastIntentLocked(null, null, intent, null,
5682                                new IIntentReceiver.Stub() {
5683                                    @Override
5684                                    public void performReceive(Intent intent, int resultCode,
5685                                            String data, Bundle extras, boolean ordered,
5686                                            boolean sticky, int sendingUser) {
5687                                        synchronized (ActivityManagerService.this) {
5688                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5689                                                    true, false);
5690                                        }
5691                                    }
5692                                },
5693                                0, null, null,
5694                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5695                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5696                                userId);
5697                    }
5698                }
5699                scheduleStartProfilesLocked();
5700            }
5701        }
5702    }
5703
5704    final void ensureBootCompleted() {
5705        boolean booting;
5706        boolean enableScreen;
5707        synchronized (this) {
5708            booting = mBooting;
5709            mBooting = false;
5710            enableScreen = !mBooted;
5711            mBooted = true;
5712        }
5713
5714        if (booting) {
5715            finishBooting();
5716        }
5717
5718        if (enableScreen) {
5719            enableScreenAfterBoot();
5720        }
5721    }
5722
5723    @Override
5724    public final void activityResumed(IBinder token) {
5725        final long origId = Binder.clearCallingIdentity();
5726        synchronized(this) {
5727            ActivityStack stack = ActivityRecord.getStackLocked(token);
5728            if (stack != null) {
5729                ActivityRecord.activityResumedLocked(token);
5730            }
5731        }
5732        Binder.restoreCallingIdentity(origId);
5733    }
5734
5735    @Override
5736    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5737        final long origId = Binder.clearCallingIdentity();
5738        synchronized(this) {
5739            ActivityStack stack = ActivityRecord.getStackLocked(token);
5740            if (stack != null) {
5741                stack.activityPausedLocked(token, false, persistentState);
5742            }
5743        }
5744        Binder.restoreCallingIdentity(origId);
5745    }
5746
5747    @Override
5748    public final void activityStopped(IBinder token, Bundle icicle,
5749            PersistableBundle persistentState, CharSequence description) {
5750        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5751
5752        // Refuse possible leaked file descriptors
5753        if (icicle != null && icicle.hasFileDescriptors()) {
5754            throw new IllegalArgumentException("File descriptors passed in Bundle");
5755        }
5756
5757        final long origId = Binder.clearCallingIdentity();
5758
5759        synchronized (this) {
5760            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5761            if (r != null) {
5762                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5763            }
5764        }
5765
5766        trimApplications();
5767
5768        Binder.restoreCallingIdentity(origId);
5769    }
5770
5771    @Override
5772    public final void activityDestroyed(IBinder token) {
5773        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5774        synchronized (this) {
5775            ActivityStack stack = ActivityRecord.getStackLocked(token);
5776            if (stack != null) {
5777                stack.activityDestroyedLocked(token);
5778            }
5779        }
5780    }
5781
5782    @Override
5783    public final void mediaResourcesReleased(IBinder token) {
5784        final long origId = Binder.clearCallingIdentity();
5785        try {
5786            synchronized (this) {
5787                ActivityStack stack = ActivityRecord.getStackLocked(token);
5788                if (stack != null) {
5789                    stack.mediaResourcesReleased(token);
5790                }
5791            }
5792        } finally {
5793            Binder.restoreCallingIdentity(origId);
5794        }
5795    }
5796
5797    @Override
5798    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5799        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5800    }
5801
5802    @Override
5803    public final void notifyEnterAnimationComplete(IBinder token) {
5804        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5805    }
5806
5807    @Override
5808    public String getCallingPackage(IBinder token) {
5809        synchronized (this) {
5810            ActivityRecord r = getCallingRecordLocked(token);
5811            return r != null ? r.info.packageName : null;
5812        }
5813    }
5814
5815    @Override
5816    public ComponentName getCallingActivity(IBinder token) {
5817        synchronized (this) {
5818            ActivityRecord r = getCallingRecordLocked(token);
5819            return r != null ? r.intent.getComponent() : null;
5820        }
5821    }
5822
5823    private ActivityRecord getCallingRecordLocked(IBinder token) {
5824        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5825        if (r == null) {
5826            return null;
5827        }
5828        return r.resultTo;
5829    }
5830
5831    @Override
5832    public ComponentName getActivityClassForToken(IBinder token) {
5833        synchronized(this) {
5834            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5835            if (r == null) {
5836                return null;
5837            }
5838            return r.intent.getComponent();
5839        }
5840    }
5841
5842    @Override
5843    public String getPackageForToken(IBinder token) {
5844        synchronized(this) {
5845            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5846            if (r == null) {
5847                return null;
5848            }
5849            return r.packageName;
5850        }
5851    }
5852
5853    @Override
5854    public IIntentSender getIntentSender(int type,
5855            String packageName, IBinder token, String resultWho,
5856            int requestCode, Intent[] intents, String[] resolvedTypes,
5857            int flags, Bundle options, int userId) {
5858        enforceNotIsolatedCaller("getIntentSender");
5859        // Refuse possible leaked file descriptors
5860        if (intents != null) {
5861            if (intents.length < 1) {
5862                throw new IllegalArgumentException("Intents array length must be >= 1");
5863            }
5864            for (int i=0; i<intents.length; i++) {
5865                Intent intent = intents[i];
5866                if (intent != null) {
5867                    if (intent.hasFileDescriptors()) {
5868                        throw new IllegalArgumentException("File descriptors passed in Intent");
5869                    }
5870                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5871                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5872                        throw new IllegalArgumentException(
5873                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5874                    }
5875                    intents[i] = new Intent(intent);
5876                }
5877            }
5878            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5879                throw new IllegalArgumentException(
5880                        "Intent array length does not match resolvedTypes length");
5881            }
5882        }
5883        if (options != null) {
5884            if (options.hasFileDescriptors()) {
5885                throw new IllegalArgumentException("File descriptors passed in options");
5886            }
5887        }
5888
5889        synchronized(this) {
5890            int callingUid = Binder.getCallingUid();
5891            int origUserId = userId;
5892            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5893                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5894                    ALLOW_NON_FULL, "getIntentSender", null);
5895            if (origUserId == UserHandle.USER_CURRENT) {
5896                // We don't want to evaluate this until the pending intent is
5897                // actually executed.  However, we do want to always do the
5898                // security checking for it above.
5899                userId = UserHandle.USER_CURRENT;
5900            }
5901            try {
5902                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5903                    int uid = AppGlobals.getPackageManager()
5904                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5905                    if (!UserHandle.isSameApp(callingUid, uid)) {
5906                        String msg = "Permission Denial: getIntentSender() from pid="
5907                            + Binder.getCallingPid()
5908                            + ", uid=" + Binder.getCallingUid()
5909                            + ", (need uid=" + uid + ")"
5910                            + " is not allowed to send as package " + packageName;
5911                        Slog.w(TAG, msg);
5912                        throw new SecurityException(msg);
5913                    }
5914                }
5915
5916                return getIntentSenderLocked(type, packageName, callingUid, userId,
5917                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5918
5919            } catch (RemoteException e) {
5920                throw new SecurityException(e);
5921            }
5922        }
5923    }
5924
5925    IIntentSender getIntentSenderLocked(int type, String packageName,
5926            int callingUid, int userId, IBinder token, String resultWho,
5927            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5928            Bundle options) {
5929        if (DEBUG_MU)
5930            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5931        ActivityRecord activity = null;
5932        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5933            activity = ActivityRecord.isInStackLocked(token);
5934            if (activity == null) {
5935                return null;
5936            }
5937            if (activity.finishing) {
5938                return null;
5939            }
5940        }
5941
5942        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5943        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5944        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5945        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5946                |PendingIntent.FLAG_UPDATE_CURRENT);
5947
5948        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5949                type, packageName, activity, resultWho,
5950                requestCode, intents, resolvedTypes, flags, options, userId);
5951        WeakReference<PendingIntentRecord> ref;
5952        ref = mIntentSenderRecords.get(key);
5953        PendingIntentRecord rec = ref != null ? ref.get() : null;
5954        if (rec != null) {
5955            if (!cancelCurrent) {
5956                if (updateCurrent) {
5957                    if (rec.key.requestIntent != null) {
5958                        rec.key.requestIntent.replaceExtras(intents != null ?
5959                                intents[intents.length - 1] : null);
5960                    }
5961                    if (intents != null) {
5962                        intents[intents.length-1] = rec.key.requestIntent;
5963                        rec.key.allIntents = intents;
5964                        rec.key.allResolvedTypes = resolvedTypes;
5965                    } else {
5966                        rec.key.allIntents = null;
5967                        rec.key.allResolvedTypes = null;
5968                    }
5969                }
5970                return rec;
5971            }
5972            rec.canceled = true;
5973            mIntentSenderRecords.remove(key);
5974        }
5975        if (noCreate) {
5976            return rec;
5977        }
5978        rec = new PendingIntentRecord(this, key, callingUid);
5979        mIntentSenderRecords.put(key, rec.ref);
5980        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5981            if (activity.pendingResults == null) {
5982                activity.pendingResults
5983                        = new HashSet<WeakReference<PendingIntentRecord>>();
5984            }
5985            activity.pendingResults.add(rec.ref);
5986        }
5987        return rec;
5988    }
5989
5990    @Override
5991    public void cancelIntentSender(IIntentSender sender) {
5992        if (!(sender instanceof PendingIntentRecord)) {
5993            return;
5994        }
5995        synchronized(this) {
5996            PendingIntentRecord rec = (PendingIntentRecord)sender;
5997            try {
5998                int uid = AppGlobals.getPackageManager()
5999                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6000                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6001                    String msg = "Permission Denial: cancelIntentSender() from pid="
6002                        + Binder.getCallingPid()
6003                        + ", uid=" + Binder.getCallingUid()
6004                        + " is not allowed to cancel packges "
6005                        + rec.key.packageName;
6006                    Slog.w(TAG, msg);
6007                    throw new SecurityException(msg);
6008                }
6009            } catch (RemoteException e) {
6010                throw new SecurityException(e);
6011            }
6012            cancelIntentSenderLocked(rec, true);
6013        }
6014    }
6015
6016    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6017        rec.canceled = true;
6018        mIntentSenderRecords.remove(rec.key);
6019        if (cleanActivity && rec.key.activity != null) {
6020            rec.key.activity.pendingResults.remove(rec.ref);
6021        }
6022    }
6023
6024    @Override
6025    public String getPackageForIntentSender(IIntentSender pendingResult) {
6026        if (!(pendingResult instanceof PendingIntentRecord)) {
6027            return null;
6028        }
6029        try {
6030            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6031            return res.key.packageName;
6032        } catch (ClassCastException e) {
6033        }
6034        return null;
6035    }
6036
6037    @Override
6038    public int getUidForIntentSender(IIntentSender sender) {
6039        if (sender instanceof PendingIntentRecord) {
6040            try {
6041                PendingIntentRecord res = (PendingIntentRecord)sender;
6042                return res.uid;
6043            } catch (ClassCastException e) {
6044            }
6045        }
6046        return -1;
6047    }
6048
6049    @Override
6050    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6051        if (!(pendingResult instanceof PendingIntentRecord)) {
6052            return false;
6053        }
6054        try {
6055            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6056            if (res.key.allIntents == null) {
6057                return false;
6058            }
6059            for (int i=0; i<res.key.allIntents.length; i++) {
6060                Intent intent = res.key.allIntents[i];
6061                if (intent.getPackage() != null && intent.getComponent() != null) {
6062                    return false;
6063                }
6064            }
6065            return true;
6066        } catch (ClassCastException e) {
6067        }
6068        return false;
6069    }
6070
6071    @Override
6072    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6073        if (!(pendingResult instanceof PendingIntentRecord)) {
6074            return false;
6075        }
6076        try {
6077            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6078            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6079                return true;
6080            }
6081            return false;
6082        } catch (ClassCastException e) {
6083        }
6084        return false;
6085    }
6086
6087    @Override
6088    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6089        if (!(pendingResult instanceof PendingIntentRecord)) {
6090            return null;
6091        }
6092        try {
6093            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6094            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6095        } catch (ClassCastException e) {
6096        }
6097        return null;
6098    }
6099
6100    @Override
6101    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6102        if (!(pendingResult instanceof PendingIntentRecord)) {
6103            return null;
6104        }
6105        try {
6106            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6107            Intent intent = res.key.requestIntent;
6108            if (intent != null) {
6109                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6110                        || res.lastTagPrefix.equals(prefix))) {
6111                    return res.lastTag;
6112                }
6113                res.lastTagPrefix = prefix;
6114                StringBuilder sb = new StringBuilder(128);
6115                if (prefix != null) {
6116                    sb.append(prefix);
6117                }
6118                if (intent.getAction() != null) {
6119                    sb.append(intent.getAction());
6120                } else if (intent.getComponent() != null) {
6121                    intent.getComponent().appendShortString(sb);
6122                } else {
6123                    sb.append("?");
6124                }
6125                return res.lastTag = sb.toString();
6126            }
6127        } catch (ClassCastException e) {
6128        }
6129        return null;
6130    }
6131
6132    @Override
6133    public void setProcessLimit(int max) {
6134        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6135                "setProcessLimit()");
6136        synchronized (this) {
6137            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6138            mProcessLimitOverride = max;
6139        }
6140        trimApplications();
6141    }
6142
6143    @Override
6144    public int getProcessLimit() {
6145        synchronized (this) {
6146            return mProcessLimitOverride;
6147        }
6148    }
6149
6150    void foregroundTokenDied(ForegroundToken token) {
6151        synchronized (ActivityManagerService.this) {
6152            synchronized (mPidsSelfLocked) {
6153                ForegroundToken cur
6154                    = mForegroundProcesses.get(token.pid);
6155                if (cur != token) {
6156                    return;
6157                }
6158                mForegroundProcesses.remove(token.pid);
6159                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6160                if (pr == null) {
6161                    return;
6162                }
6163                pr.forcingToForeground = null;
6164                updateProcessForegroundLocked(pr, false, false);
6165            }
6166            updateOomAdjLocked();
6167        }
6168    }
6169
6170    @Override
6171    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6172        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6173                "setProcessForeground()");
6174        synchronized(this) {
6175            boolean changed = false;
6176
6177            synchronized (mPidsSelfLocked) {
6178                ProcessRecord pr = mPidsSelfLocked.get(pid);
6179                if (pr == null && isForeground) {
6180                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6181                    return;
6182                }
6183                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6184                if (oldToken != null) {
6185                    oldToken.token.unlinkToDeath(oldToken, 0);
6186                    mForegroundProcesses.remove(pid);
6187                    if (pr != null) {
6188                        pr.forcingToForeground = null;
6189                    }
6190                    changed = true;
6191                }
6192                if (isForeground && token != null) {
6193                    ForegroundToken newToken = new ForegroundToken() {
6194                        @Override
6195                        public void binderDied() {
6196                            foregroundTokenDied(this);
6197                        }
6198                    };
6199                    newToken.pid = pid;
6200                    newToken.token = token;
6201                    try {
6202                        token.linkToDeath(newToken, 0);
6203                        mForegroundProcesses.put(pid, newToken);
6204                        pr.forcingToForeground = token;
6205                        changed = true;
6206                    } catch (RemoteException e) {
6207                        // If the process died while doing this, we will later
6208                        // do the cleanup with the process death link.
6209                    }
6210                }
6211            }
6212
6213            if (changed) {
6214                updateOomAdjLocked();
6215            }
6216        }
6217    }
6218
6219    // =========================================================
6220    // PERMISSIONS
6221    // =========================================================
6222
6223    static class PermissionController extends IPermissionController.Stub {
6224        ActivityManagerService mActivityManagerService;
6225        PermissionController(ActivityManagerService activityManagerService) {
6226            mActivityManagerService = activityManagerService;
6227        }
6228
6229        @Override
6230        public boolean checkPermission(String permission, int pid, int uid) {
6231            return mActivityManagerService.checkPermission(permission, pid,
6232                    uid) == PackageManager.PERMISSION_GRANTED;
6233        }
6234    }
6235
6236    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6237        @Override
6238        public int checkComponentPermission(String permission, int pid, int uid,
6239                int owningUid, boolean exported) {
6240            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6241                    owningUid, exported);
6242        }
6243
6244        @Override
6245        public Object getAMSLock() {
6246            return ActivityManagerService.this;
6247        }
6248    }
6249
6250    /**
6251     * This can be called with or without the global lock held.
6252     */
6253    int checkComponentPermission(String permission, int pid, int uid,
6254            int owningUid, boolean exported) {
6255        // We might be performing an operation on behalf of an indirect binder
6256        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6257        // client identity accordingly before proceeding.
6258        Identity tlsIdentity = sCallerIdentity.get();
6259        if (tlsIdentity != null) {
6260            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6261                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6262            uid = tlsIdentity.uid;
6263            pid = tlsIdentity.pid;
6264        }
6265
6266        if (pid == MY_PID) {
6267            return PackageManager.PERMISSION_GRANTED;
6268        }
6269
6270        return ActivityManager.checkComponentPermission(permission, uid,
6271                owningUid, exported);
6272    }
6273
6274    /**
6275     * As the only public entry point for permissions checking, this method
6276     * can enforce the semantic that requesting a check on a null global
6277     * permission is automatically denied.  (Internally a null permission
6278     * string is used when calling {@link #checkComponentPermission} in cases
6279     * when only uid-based security is needed.)
6280     *
6281     * This can be called with or without the global lock held.
6282     */
6283    @Override
6284    public int checkPermission(String permission, int pid, int uid) {
6285        if (permission == null) {
6286            return PackageManager.PERMISSION_DENIED;
6287        }
6288        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6289    }
6290
6291    /**
6292     * Binder IPC calls go through the public entry point.
6293     * This can be called with or without the global lock held.
6294     */
6295    int checkCallingPermission(String permission) {
6296        return checkPermission(permission,
6297                Binder.getCallingPid(),
6298                UserHandle.getAppId(Binder.getCallingUid()));
6299    }
6300
6301    /**
6302     * This can be called with or without the global lock held.
6303     */
6304    void enforceCallingPermission(String permission, String func) {
6305        if (checkCallingPermission(permission)
6306                == PackageManager.PERMISSION_GRANTED) {
6307            return;
6308        }
6309
6310        String msg = "Permission Denial: " + func + " from pid="
6311                + Binder.getCallingPid()
6312                + ", uid=" + Binder.getCallingUid()
6313                + " requires " + permission;
6314        Slog.w(TAG, msg);
6315        throw new SecurityException(msg);
6316    }
6317
6318    /**
6319     * Determine if UID is holding permissions required to access {@link Uri} in
6320     * the given {@link ProviderInfo}. Final permission checking is always done
6321     * in {@link ContentProvider}.
6322     */
6323    private final boolean checkHoldingPermissionsLocked(
6324            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6325        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6326                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6327        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6328            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6329                    != PERMISSION_GRANTED) {
6330                return false;
6331            }
6332        }
6333        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6334    }
6335
6336    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6337            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6338        if (pi.applicationInfo.uid == uid) {
6339            return true;
6340        } else if (!pi.exported) {
6341            return false;
6342        }
6343
6344        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6345        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6346        try {
6347            // check if target holds top-level <provider> permissions
6348            if (!readMet && pi.readPermission != null && considerUidPermissions
6349                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6350                readMet = true;
6351            }
6352            if (!writeMet && pi.writePermission != null && considerUidPermissions
6353                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6354                writeMet = true;
6355            }
6356
6357            // track if unprotected read/write is allowed; any denied
6358            // <path-permission> below removes this ability
6359            boolean allowDefaultRead = pi.readPermission == null;
6360            boolean allowDefaultWrite = pi.writePermission == null;
6361
6362            // check if target holds any <path-permission> that match uri
6363            final PathPermission[] pps = pi.pathPermissions;
6364            if (pps != null) {
6365                final String path = grantUri.uri.getPath();
6366                int i = pps.length;
6367                while (i > 0 && (!readMet || !writeMet)) {
6368                    i--;
6369                    PathPermission pp = pps[i];
6370                    if (pp.match(path)) {
6371                        if (!readMet) {
6372                            final String pprperm = pp.getReadPermission();
6373                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6374                                    + pprperm + " for " + pp.getPath()
6375                                    + ": match=" + pp.match(path)
6376                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6377                            if (pprperm != null) {
6378                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6379                                        == PERMISSION_GRANTED) {
6380                                    readMet = true;
6381                                } else {
6382                                    allowDefaultRead = false;
6383                                }
6384                            }
6385                        }
6386                        if (!writeMet) {
6387                            final String ppwperm = pp.getWritePermission();
6388                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6389                                    + ppwperm + " for " + pp.getPath()
6390                                    + ": match=" + pp.match(path)
6391                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6392                            if (ppwperm != null) {
6393                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6394                                        == PERMISSION_GRANTED) {
6395                                    writeMet = true;
6396                                } else {
6397                                    allowDefaultWrite = false;
6398                                }
6399                            }
6400                        }
6401                    }
6402                }
6403            }
6404
6405            // grant unprotected <provider> read/write, if not blocked by
6406            // <path-permission> above
6407            if (allowDefaultRead) readMet = true;
6408            if (allowDefaultWrite) writeMet = true;
6409
6410        } catch (RemoteException e) {
6411            return false;
6412        }
6413
6414        return readMet && writeMet;
6415    }
6416
6417    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6418        ProviderInfo pi = null;
6419        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6420        if (cpr != null) {
6421            pi = cpr.info;
6422        } else {
6423            try {
6424                pi = AppGlobals.getPackageManager().resolveContentProvider(
6425                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6426            } catch (RemoteException ex) {
6427            }
6428        }
6429        return pi;
6430    }
6431
6432    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6433        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6434        if (targetUris != null) {
6435            return targetUris.get(grantUri);
6436        }
6437        return null;
6438    }
6439
6440    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6441            String targetPkg, int targetUid, GrantUri grantUri) {
6442        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6443        if (targetUris == null) {
6444            targetUris = Maps.newArrayMap();
6445            mGrantedUriPermissions.put(targetUid, targetUris);
6446        }
6447
6448        UriPermission perm = targetUris.get(grantUri);
6449        if (perm == null) {
6450            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6451            targetUris.put(grantUri, perm);
6452        }
6453
6454        return perm;
6455    }
6456
6457    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6458            final int modeFlags) {
6459        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6460        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6461                : UriPermission.STRENGTH_OWNED;
6462
6463        // Root gets to do everything.
6464        if (uid == 0) {
6465            return true;
6466        }
6467
6468        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6469        if (perms == null) return false;
6470
6471        // First look for exact match
6472        final UriPermission exactPerm = perms.get(grantUri);
6473        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6474            return true;
6475        }
6476
6477        // No exact match, look for prefixes
6478        final int N = perms.size();
6479        for (int i = 0; i < N; i++) {
6480            final UriPermission perm = perms.valueAt(i);
6481            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6482                    && perm.getStrength(modeFlags) >= minStrength) {
6483                return true;
6484            }
6485        }
6486
6487        return false;
6488    }
6489
6490    @Override
6491    public int checkUriPermission(Uri uri, int pid, int uid,
6492            final int modeFlags, int userId) {
6493        enforceNotIsolatedCaller("checkUriPermission");
6494
6495        // Another redirected-binder-call permissions check as in
6496        // {@link checkComponentPermission}.
6497        Identity tlsIdentity = sCallerIdentity.get();
6498        if (tlsIdentity != null) {
6499            uid = tlsIdentity.uid;
6500            pid = tlsIdentity.pid;
6501        }
6502
6503        // Our own process gets to do everything.
6504        if (pid == MY_PID) {
6505            return PackageManager.PERMISSION_GRANTED;
6506        }
6507        synchronized (this) {
6508            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6509                    ? PackageManager.PERMISSION_GRANTED
6510                    : PackageManager.PERMISSION_DENIED;
6511        }
6512    }
6513
6514    /**
6515     * Check if the targetPkg can be granted permission to access uri by
6516     * the callingUid using the given modeFlags.  Throws a security exception
6517     * if callingUid is not allowed to do this.  Returns the uid of the target
6518     * if the URI permission grant should be performed; returns -1 if it is not
6519     * needed (for example targetPkg already has permission to access the URI).
6520     * If you already know the uid of the target, you can supply it in
6521     * lastTargetUid else set that to -1.
6522     */
6523    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6524            final int modeFlags, int lastTargetUid) {
6525        if (!Intent.isAccessUriMode(modeFlags)) {
6526            return -1;
6527        }
6528
6529        if (targetPkg != null) {
6530            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6531                    "Checking grant " + targetPkg + " permission to " + grantUri);
6532        }
6533
6534        final IPackageManager pm = AppGlobals.getPackageManager();
6535
6536        // If this is not a content: uri, we can't do anything with it.
6537        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6538            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6539                    "Can't grant URI permission for non-content URI: " + grantUri);
6540            return -1;
6541        }
6542
6543        final String authority = grantUri.uri.getAuthority();
6544        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6545        if (pi == null) {
6546            Slog.w(TAG, "No content provider found for permission check: " +
6547                    grantUri.uri.toSafeString());
6548            return -1;
6549        }
6550
6551        int targetUid = lastTargetUid;
6552        if (targetUid < 0 && targetPkg != null) {
6553            try {
6554                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6555                if (targetUid < 0) {
6556                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6557                            "Can't grant URI permission no uid for: " + targetPkg);
6558                    return -1;
6559                }
6560            } catch (RemoteException ex) {
6561                return -1;
6562            }
6563        }
6564
6565        if (targetUid >= 0) {
6566            // First...  does the target actually need this permission?
6567            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6568                // No need to grant the target this permission.
6569                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6570                        "Target " + targetPkg + " already has full permission to " + grantUri);
6571                return -1;
6572            }
6573        } else {
6574            // First...  there is no target package, so can anyone access it?
6575            boolean allowed = pi.exported;
6576            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6577                if (pi.readPermission != null) {
6578                    allowed = false;
6579                }
6580            }
6581            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6582                if (pi.writePermission != null) {
6583                    allowed = false;
6584                }
6585            }
6586            if (allowed) {
6587                return -1;
6588            }
6589        }
6590
6591        /* There is a special cross user grant if:
6592         * - The target is on another user.
6593         * - Apps on the current user can access the uri without any uid permissions.
6594         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6595         * grant uri permissions.
6596         */
6597        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6598                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6599                modeFlags, false /*without considering the uid permissions*/);
6600
6601        // Second...  is the provider allowing granting of URI permissions?
6602        if (!specialCrossUserGrant) {
6603            if (!pi.grantUriPermissions) {
6604                throw new SecurityException("Provider " + pi.packageName
6605                        + "/" + pi.name
6606                        + " does not allow granting of Uri permissions (uri "
6607                        + grantUri + ")");
6608            }
6609            if (pi.uriPermissionPatterns != null) {
6610                final int N = pi.uriPermissionPatterns.length;
6611                boolean allowed = false;
6612                for (int i=0; i<N; i++) {
6613                    if (pi.uriPermissionPatterns[i] != null
6614                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6615                        allowed = true;
6616                        break;
6617                    }
6618                }
6619                if (!allowed) {
6620                    throw new SecurityException("Provider " + pi.packageName
6621                            + "/" + pi.name
6622                            + " does not allow granting of permission to path of Uri "
6623                            + grantUri);
6624                }
6625            }
6626        }
6627
6628        // Third...  does the caller itself have permission to access
6629        // this uri?
6630        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6631            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6632                // Require they hold a strong enough Uri permission
6633                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6634                    throw new SecurityException("Uid " + callingUid
6635                            + " does not have permission to uri " + grantUri);
6636                }
6637            }
6638        }
6639        return targetUid;
6640    }
6641
6642    @Override
6643    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6644            final int modeFlags, int userId) {
6645        enforceNotIsolatedCaller("checkGrantUriPermission");
6646        synchronized(this) {
6647            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6648                    new GrantUri(userId, uri, false), modeFlags, -1);
6649        }
6650    }
6651
6652    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6653            final int modeFlags, UriPermissionOwner owner) {
6654        if (!Intent.isAccessUriMode(modeFlags)) {
6655            return;
6656        }
6657
6658        // So here we are: the caller has the assumed permission
6659        // to the uri, and the target doesn't.  Let's now give this to
6660        // the target.
6661
6662        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6663                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6664
6665        final String authority = grantUri.uri.getAuthority();
6666        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6667        if (pi == null) {
6668            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6669            return;
6670        }
6671
6672        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6673            grantUri.prefix = true;
6674        }
6675        final UriPermission perm = findOrCreateUriPermissionLocked(
6676                pi.packageName, targetPkg, targetUid, grantUri);
6677        perm.grantModes(modeFlags, owner);
6678    }
6679
6680    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6681            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6682        if (targetPkg == null) {
6683            throw new NullPointerException("targetPkg");
6684        }
6685        int targetUid;
6686        final IPackageManager pm = AppGlobals.getPackageManager();
6687        try {
6688            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6689        } catch (RemoteException ex) {
6690            return;
6691        }
6692
6693        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6694                targetUid);
6695        if (targetUid < 0) {
6696            return;
6697        }
6698
6699        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6700                owner);
6701    }
6702
6703    static class NeededUriGrants extends ArrayList<GrantUri> {
6704        final String targetPkg;
6705        final int targetUid;
6706        final int flags;
6707
6708        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6709            this.targetPkg = targetPkg;
6710            this.targetUid = targetUid;
6711            this.flags = flags;
6712        }
6713    }
6714
6715    /**
6716     * Like checkGrantUriPermissionLocked, but takes an Intent.
6717     */
6718    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6719            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6720        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6721                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6722                + " clip=" + (intent != null ? intent.getClipData() : null)
6723                + " from " + intent + "; flags=0x"
6724                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6725
6726        if (targetPkg == null) {
6727            throw new NullPointerException("targetPkg");
6728        }
6729
6730        if (intent == null) {
6731            return null;
6732        }
6733        Uri data = intent.getData();
6734        ClipData clip = intent.getClipData();
6735        if (data == null && clip == null) {
6736            return null;
6737        }
6738        // Default userId for uris in the intent (if they don't specify it themselves)
6739        int contentUserHint = intent.getContentUserHint();
6740        if (contentUserHint == UserHandle.USER_CURRENT) {
6741            contentUserHint = UserHandle.getUserId(callingUid);
6742        }
6743        final IPackageManager pm = AppGlobals.getPackageManager();
6744        int targetUid;
6745        if (needed != null) {
6746            targetUid = needed.targetUid;
6747        } else {
6748            try {
6749                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6750            } catch (RemoteException ex) {
6751                return null;
6752            }
6753            if (targetUid < 0) {
6754                if (DEBUG_URI_PERMISSION) {
6755                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6756                            + " on user " + targetUserId);
6757                }
6758                return null;
6759            }
6760        }
6761        if (data != null) {
6762            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6763            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6764                    targetUid);
6765            if (targetUid > 0) {
6766                if (needed == null) {
6767                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6768                }
6769                needed.add(grantUri);
6770            }
6771        }
6772        if (clip != null) {
6773            for (int i=0; i<clip.getItemCount(); i++) {
6774                Uri uri = clip.getItemAt(i).getUri();
6775                if (uri != null) {
6776                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6777                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6778                            targetUid);
6779                    if (targetUid > 0) {
6780                        if (needed == null) {
6781                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6782                        }
6783                        needed.add(grantUri);
6784                    }
6785                } else {
6786                    Intent clipIntent = clip.getItemAt(i).getIntent();
6787                    if (clipIntent != null) {
6788                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6789                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6790                        if (newNeeded != null) {
6791                            needed = newNeeded;
6792                        }
6793                    }
6794                }
6795            }
6796        }
6797
6798        return needed;
6799    }
6800
6801    /**
6802     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6803     */
6804    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6805            UriPermissionOwner owner) {
6806        if (needed != null) {
6807            for (int i=0; i<needed.size(); i++) {
6808                GrantUri grantUri = needed.get(i);
6809                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6810                        grantUri, needed.flags, owner);
6811            }
6812        }
6813    }
6814
6815    void grantUriPermissionFromIntentLocked(int callingUid,
6816            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6817        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6818                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6819        if (needed == null) {
6820            return;
6821        }
6822
6823        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6824    }
6825
6826    @Override
6827    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6828            final int modeFlags, int userId) {
6829        enforceNotIsolatedCaller("grantUriPermission");
6830        GrantUri grantUri = new GrantUri(userId, uri, false);
6831        synchronized(this) {
6832            final ProcessRecord r = getRecordForAppLocked(caller);
6833            if (r == null) {
6834                throw new SecurityException("Unable to find app for caller "
6835                        + caller
6836                        + " when granting permission to uri " + grantUri);
6837            }
6838            if (targetPkg == null) {
6839                throw new IllegalArgumentException("null target");
6840            }
6841            if (grantUri == null) {
6842                throw new IllegalArgumentException("null uri");
6843            }
6844
6845            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6846                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6847                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6848                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6849
6850            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6851                    UserHandle.getUserId(r.uid));
6852        }
6853    }
6854
6855    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6856        if (perm.modeFlags == 0) {
6857            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6858                    perm.targetUid);
6859            if (perms != null) {
6860                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6861                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6862
6863                perms.remove(perm.uri);
6864                if (perms.isEmpty()) {
6865                    mGrantedUriPermissions.remove(perm.targetUid);
6866                }
6867            }
6868        }
6869    }
6870
6871    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6872        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6873
6874        final IPackageManager pm = AppGlobals.getPackageManager();
6875        final String authority = grantUri.uri.getAuthority();
6876        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6877        if (pi == null) {
6878            Slog.w(TAG, "No content provider found for permission revoke: "
6879                    + grantUri.toSafeString());
6880            return;
6881        }
6882
6883        // Does the caller have this permission on the URI?
6884        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6885            // Right now, if you are not the original owner of the permission,
6886            // you are not allowed to revoke it.
6887            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6888                throw new SecurityException("Uid " + callingUid
6889                        + " does not have permission to uri " + grantUri);
6890            //}
6891        }
6892
6893        boolean persistChanged = false;
6894
6895        // Go through all of the permissions and remove any that match.
6896        int N = mGrantedUriPermissions.size();
6897        for (int i = 0; i < N; i++) {
6898            final int targetUid = mGrantedUriPermissions.keyAt(i);
6899            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6900
6901            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6902                final UriPermission perm = it.next();
6903                if (perm.uri.sourceUserId == grantUri.sourceUserId
6904                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6905                    if (DEBUG_URI_PERMISSION)
6906                        Slog.v(TAG,
6907                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6908                    persistChanged |= perm.revokeModes(
6909                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6910                    if (perm.modeFlags == 0) {
6911                        it.remove();
6912                    }
6913                }
6914            }
6915
6916            if (perms.isEmpty()) {
6917                mGrantedUriPermissions.remove(targetUid);
6918                N--;
6919                i--;
6920            }
6921        }
6922
6923        if (persistChanged) {
6924            schedulePersistUriGrants();
6925        }
6926    }
6927
6928    @Override
6929    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6930            int userId) {
6931        enforceNotIsolatedCaller("revokeUriPermission");
6932        synchronized(this) {
6933            final ProcessRecord r = getRecordForAppLocked(caller);
6934            if (r == null) {
6935                throw new SecurityException("Unable to find app for caller "
6936                        + caller
6937                        + " when revoking permission to uri " + uri);
6938            }
6939            if (uri == null) {
6940                Slog.w(TAG, "revokeUriPermission: null uri");
6941                return;
6942            }
6943
6944            if (!Intent.isAccessUriMode(modeFlags)) {
6945                return;
6946            }
6947
6948            final IPackageManager pm = AppGlobals.getPackageManager();
6949            final String authority = uri.getAuthority();
6950            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6951            if (pi == null) {
6952                Slog.w(TAG, "No content provider found for permission revoke: "
6953                        + uri.toSafeString());
6954                return;
6955            }
6956
6957            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6958        }
6959    }
6960
6961    /**
6962     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6963     * given package.
6964     *
6965     * @param packageName Package name to match, or {@code null} to apply to all
6966     *            packages.
6967     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6968     *            to all users.
6969     * @param persistable If persistable grants should be removed.
6970     */
6971    private void removeUriPermissionsForPackageLocked(
6972            String packageName, int userHandle, boolean persistable) {
6973        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6974            throw new IllegalArgumentException("Must narrow by either package or user");
6975        }
6976
6977        boolean persistChanged = false;
6978
6979        int N = mGrantedUriPermissions.size();
6980        for (int i = 0; i < N; i++) {
6981            final int targetUid = mGrantedUriPermissions.keyAt(i);
6982            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6983
6984            // Only inspect grants matching user
6985            if (userHandle == UserHandle.USER_ALL
6986                    || userHandle == UserHandle.getUserId(targetUid)) {
6987                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6988                    final UriPermission perm = it.next();
6989
6990                    // Only inspect grants matching package
6991                    if (packageName == null || perm.sourcePkg.equals(packageName)
6992                            || perm.targetPkg.equals(packageName)) {
6993                        persistChanged |= perm.revokeModes(
6994                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6995
6996                        // Only remove when no modes remain; any persisted grants
6997                        // will keep this alive.
6998                        if (perm.modeFlags == 0) {
6999                            it.remove();
7000                        }
7001                    }
7002                }
7003
7004                if (perms.isEmpty()) {
7005                    mGrantedUriPermissions.remove(targetUid);
7006                    N--;
7007                    i--;
7008                }
7009            }
7010        }
7011
7012        if (persistChanged) {
7013            schedulePersistUriGrants();
7014        }
7015    }
7016
7017    @Override
7018    public IBinder newUriPermissionOwner(String name) {
7019        enforceNotIsolatedCaller("newUriPermissionOwner");
7020        synchronized(this) {
7021            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7022            return owner.getExternalTokenLocked();
7023        }
7024    }
7025
7026    @Override
7027    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7028            final int modeFlags, int sourceUserId, int targetUserId) {
7029        synchronized(this) {
7030            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7031            if (owner == null) {
7032                throw new IllegalArgumentException("Unknown owner: " + token);
7033            }
7034            if (fromUid != Binder.getCallingUid()) {
7035                if (Binder.getCallingUid() != Process.myUid()) {
7036                    // Only system code can grant URI permissions on behalf
7037                    // of other users.
7038                    throw new SecurityException("nice try");
7039                }
7040            }
7041            if (targetPkg == null) {
7042                throw new IllegalArgumentException("null target");
7043            }
7044            if (uri == null) {
7045                throw new IllegalArgumentException("null uri");
7046            }
7047
7048            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7049                    modeFlags, owner, targetUserId);
7050        }
7051    }
7052
7053    @Override
7054    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7055        synchronized(this) {
7056            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7057            if (owner == null) {
7058                throw new IllegalArgumentException("Unknown owner: " + token);
7059            }
7060
7061            if (uri == null) {
7062                owner.removeUriPermissionsLocked(mode);
7063            } else {
7064                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7065            }
7066        }
7067    }
7068
7069    private void schedulePersistUriGrants() {
7070        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7071            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7072                    10 * DateUtils.SECOND_IN_MILLIS);
7073        }
7074    }
7075
7076    private void writeGrantedUriPermissions() {
7077        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7078
7079        // Snapshot permissions so we can persist without lock
7080        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7081        synchronized (this) {
7082            final int size = mGrantedUriPermissions.size();
7083            for (int i = 0; i < size; i++) {
7084                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7085                for (UriPermission perm : perms.values()) {
7086                    if (perm.persistedModeFlags != 0) {
7087                        persist.add(perm.snapshot());
7088                    }
7089                }
7090            }
7091        }
7092
7093        FileOutputStream fos = null;
7094        try {
7095            fos = mGrantFile.startWrite();
7096
7097            XmlSerializer out = new FastXmlSerializer();
7098            out.setOutput(fos, "utf-8");
7099            out.startDocument(null, true);
7100            out.startTag(null, TAG_URI_GRANTS);
7101            for (UriPermission.Snapshot perm : persist) {
7102                out.startTag(null, TAG_URI_GRANT);
7103                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7104                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7105                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7106                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7107                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7108                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7109                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7110                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7111                out.endTag(null, TAG_URI_GRANT);
7112            }
7113            out.endTag(null, TAG_URI_GRANTS);
7114            out.endDocument();
7115
7116            mGrantFile.finishWrite(fos);
7117        } catch (IOException e) {
7118            if (fos != null) {
7119                mGrantFile.failWrite(fos);
7120            }
7121        }
7122    }
7123
7124    private void readGrantedUriPermissionsLocked() {
7125        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7126
7127        final long now = System.currentTimeMillis();
7128
7129        FileInputStream fis = null;
7130        try {
7131            fis = mGrantFile.openRead();
7132            final XmlPullParser in = Xml.newPullParser();
7133            in.setInput(fis, null);
7134
7135            int type;
7136            while ((type = in.next()) != END_DOCUMENT) {
7137                final String tag = in.getName();
7138                if (type == START_TAG) {
7139                    if (TAG_URI_GRANT.equals(tag)) {
7140                        final int sourceUserId;
7141                        final int targetUserId;
7142                        final int userHandle = readIntAttribute(in,
7143                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7144                        if (userHandle != UserHandle.USER_NULL) {
7145                            // For backwards compatibility.
7146                            sourceUserId = userHandle;
7147                            targetUserId = userHandle;
7148                        } else {
7149                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7150                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7151                        }
7152                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7153                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7154                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7155                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7156                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7157                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7158
7159                        // Sanity check that provider still belongs to source package
7160                        final ProviderInfo pi = getProviderInfoLocked(
7161                                uri.getAuthority(), sourceUserId);
7162                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7163                            int targetUid = -1;
7164                            try {
7165                                targetUid = AppGlobals.getPackageManager()
7166                                        .getPackageUid(targetPkg, targetUserId);
7167                            } catch (RemoteException e) {
7168                            }
7169                            if (targetUid != -1) {
7170                                final UriPermission perm = findOrCreateUriPermissionLocked(
7171                                        sourcePkg, targetPkg, targetUid,
7172                                        new GrantUri(sourceUserId, uri, prefix));
7173                                perm.initPersistedModes(modeFlags, createdTime);
7174                            }
7175                        } else {
7176                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7177                                    + " but instead found " + pi);
7178                        }
7179                    }
7180                }
7181            }
7182        } catch (FileNotFoundException e) {
7183            // Missing grants is okay
7184        } catch (IOException e) {
7185            Log.wtf(TAG, "Failed reading Uri grants", e);
7186        } catch (XmlPullParserException e) {
7187            Log.wtf(TAG, "Failed reading Uri grants", e);
7188        } finally {
7189            IoUtils.closeQuietly(fis);
7190        }
7191    }
7192
7193    @Override
7194    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7195        enforceNotIsolatedCaller("takePersistableUriPermission");
7196
7197        Preconditions.checkFlagsArgument(modeFlags,
7198                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7199
7200        synchronized (this) {
7201            final int callingUid = Binder.getCallingUid();
7202            boolean persistChanged = false;
7203            GrantUri grantUri = new GrantUri(userId, uri, false);
7204
7205            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7206                    new GrantUri(userId, uri, false));
7207            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7208                    new GrantUri(userId, uri, true));
7209
7210            final boolean exactValid = (exactPerm != null)
7211                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7212            final boolean prefixValid = (prefixPerm != null)
7213                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7214
7215            if (!(exactValid || prefixValid)) {
7216                throw new SecurityException("No persistable permission grants found for UID "
7217                        + callingUid + " and Uri " + grantUri.toSafeString());
7218            }
7219
7220            if (exactValid) {
7221                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7222            }
7223            if (prefixValid) {
7224                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7225            }
7226
7227            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7228
7229            if (persistChanged) {
7230                schedulePersistUriGrants();
7231            }
7232        }
7233    }
7234
7235    @Override
7236    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7237        enforceNotIsolatedCaller("releasePersistableUriPermission");
7238
7239        Preconditions.checkFlagsArgument(modeFlags,
7240                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7241
7242        synchronized (this) {
7243            final int callingUid = Binder.getCallingUid();
7244            boolean persistChanged = false;
7245
7246            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7247                    new GrantUri(userId, uri, false));
7248            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7249                    new GrantUri(userId, uri, true));
7250            if (exactPerm == null && prefixPerm == null) {
7251                throw new SecurityException("No permission grants found for UID " + callingUid
7252                        + " and Uri " + uri.toSafeString());
7253            }
7254
7255            if (exactPerm != null) {
7256                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7257                removeUriPermissionIfNeededLocked(exactPerm);
7258            }
7259            if (prefixPerm != null) {
7260                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7261                removeUriPermissionIfNeededLocked(prefixPerm);
7262            }
7263
7264            if (persistChanged) {
7265                schedulePersistUriGrants();
7266            }
7267        }
7268    }
7269
7270    /**
7271     * Prune any older {@link UriPermission} for the given UID until outstanding
7272     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7273     *
7274     * @return if any mutations occured that require persisting.
7275     */
7276    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7277        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7278        if (perms == null) return false;
7279        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7280
7281        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7282        for (UriPermission perm : perms.values()) {
7283            if (perm.persistedModeFlags != 0) {
7284                persisted.add(perm);
7285            }
7286        }
7287
7288        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7289        if (trimCount <= 0) return false;
7290
7291        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7292        for (int i = 0; i < trimCount; i++) {
7293            final UriPermission perm = persisted.get(i);
7294
7295            if (DEBUG_URI_PERMISSION) {
7296                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7297            }
7298
7299            perm.releasePersistableModes(~0);
7300            removeUriPermissionIfNeededLocked(perm);
7301        }
7302
7303        return true;
7304    }
7305
7306    @Override
7307    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7308            String packageName, boolean incoming) {
7309        enforceNotIsolatedCaller("getPersistedUriPermissions");
7310        Preconditions.checkNotNull(packageName, "packageName");
7311
7312        final int callingUid = Binder.getCallingUid();
7313        final IPackageManager pm = AppGlobals.getPackageManager();
7314        try {
7315            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7316            if (packageUid != callingUid) {
7317                throw new SecurityException(
7318                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7319            }
7320        } catch (RemoteException e) {
7321            throw new SecurityException("Failed to verify package name ownership");
7322        }
7323
7324        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7325        synchronized (this) {
7326            if (incoming) {
7327                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7328                        callingUid);
7329                if (perms == null) {
7330                    Slog.w(TAG, "No permission grants found for " + packageName);
7331                } else {
7332                    for (UriPermission perm : perms.values()) {
7333                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7334                            result.add(perm.buildPersistedPublicApiObject());
7335                        }
7336                    }
7337                }
7338            } else {
7339                final int size = mGrantedUriPermissions.size();
7340                for (int i = 0; i < size; i++) {
7341                    final ArrayMap<GrantUri, UriPermission> perms =
7342                            mGrantedUriPermissions.valueAt(i);
7343                    for (UriPermission perm : perms.values()) {
7344                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7345                            result.add(perm.buildPersistedPublicApiObject());
7346                        }
7347                    }
7348                }
7349            }
7350        }
7351        return new ParceledListSlice<android.content.UriPermission>(result);
7352    }
7353
7354    @Override
7355    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7356        synchronized (this) {
7357            ProcessRecord app =
7358                who != null ? getRecordForAppLocked(who) : null;
7359            if (app == null) return;
7360
7361            Message msg = Message.obtain();
7362            msg.what = WAIT_FOR_DEBUGGER_MSG;
7363            msg.obj = app;
7364            msg.arg1 = waiting ? 1 : 0;
7365            mHandler.sendMessage(msg);
7366        }
7367    }
7368
7369    @Override
7370    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7371        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7372        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7373        outInfo.availMem = Process.getFreeMemory();
7374        outInfo.totalMem = Process.getTotalMemory();
7375        outInfo.threshold = homeAppMem;
7376        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7377        outInfo.hiddenAppThreshold = cachedAppMem;
7378        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7379                ProcessList.SERVICE_ADJ);
7380        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7381                ProcessList.VISIBLE_APP_ADJ);
7382        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7383                ProcessList.FOREGROUND_APP_ADJ);
7384    }
7385
7386    // =========================================================
7387    // TASK MANAGEMENT
7388    // =========================================================
7389
7390    @Override
7391    public List<IAppTask> getAppTasks() {
7392        final PackageManager pm = mContext.getPackageManager();
7393        int callingUid = Binder.getCallingUid();
7394        long ident = Binder.clearCallingIdentity();
7395
7396        // Compose the list of packages for this id to test against
7397        HashSet<String> packages = new HashSet<String>();
7398        String[] uidPackages = pm.getPackagesForUid(callingUid);
7399        for (int i = 0; i < uidPackages.length; i++) {
7400            packages.add(uidPackages[i]);
7401        }
7402
7403        synchronized(this) {
7404            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7405            try {
7406                if (localLOGV) Slog.v(TAG, "getAppTasks");
7407
7408                final int N = mRecentTasks.size();
7409                for (int i = 0; i < N; i++) {
7410                    TaskRecord tr = mRecentTasks.get(i);
7411                    // Skip tasks that are not created by the caller
7412                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7413                        ActivityManager.RecentTaskInfo taskInfo =
7414                                createRecentTaskInfoFromTaskRecord(tr);
7415                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7416                        list.add(taskImpl);
7417                    }
7418                }
7419            } finally {
7420                Binder.restoreCallingIdentity(ident);
7421            }
7422            return list;
7423        }
7424    }
7425
7426    @Override
7427    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7428        final int callingUid = Binder.getCallingUid();
7429        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7430
7431        synchronized(this) {
7432            if (localLOGV) Slog.v(
7433                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7434
7435            final boolean allowed = checkCallingPermission(
7436                    android.Manifest.permission.GET_TASKS)
7437                    == PackageManager.PERMISSION_GRANTED;
7438            if (!allowed) {
7439                Slog.w(TAG, "getTasks: caller " + callingUid
7440                        + " does not hold GET_TASKS; limiting output");
7441            }
7442
7443            // TODO: Improve with MRU list from all ActivityStacks.
7444            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7445        }
7446
7447        return list;
7448    }
7449
7450    TaskRecord getMostRecentTask() {
7451        return mRecentTasks.get(0);
7452    }
7453
7454    /**
7455     * Creates a new RecentTaskInfo from a TaskRecord.
7456     */
7457    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7458        // Update the task description to reflect any changes in the task stack
7459        tr.updateTaskDescription();
7460
7461        // Compose the recent task info
7462        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7463        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7464        rti.persistentId = tr.taskId;
7465        rti.baseIntent = new Intent(tr.getBaseIntent());
7466        rti.origActivity = tr.origActivity;
7467        rti.description = tr.lastDescription;
7468        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7469        rti.userId = tr.userId;
7470        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7471        rti.firstActiveTime = tr.firstActiveTime;
7472        rti.lastActiveTime = tr.lastActiveTime;
7473        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7474        return rti;
7475    }
7476
7477    @Override
7478    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7479        final int callingUid = Binder.getCallingUid();
7480        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7481                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7482
7483        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7484        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7485        synchronized (this) {
7486            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7487                    == PackageManager.PERMISSION_GRANTED;
7488            if (!allowed) {
7489                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7490                        + " does not hold GET_TASKS; limiting output");
7491            }
7492            final boolean detailed = checkCallingPermission(
7493                    android.Manifest.permission.GET_DETAILED_TASKS)
7494                    == PackageManager.PERMISSION_GRANTED;
7495
7496            IPackageManager pm = AppGlobals.getPackageManager();
7497
7498            final int N = mRecentTasks.size();
7499            ArrayList<ActivityManager.RecentTaskInfo> res
7500                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7501                            maxNum < N ? maxNum : N);
7502
7503            final Set<Integer> includedUsers;
7504            if (includeProfiles) {
7505                includedUsers = getProfileIdsLocked(userId);
7506            } else {
7507                includedUsers = new HashSet<Integer>();
7508            }
7509            includedUsers.add(Integer.valueOf(userId));
7510
7511            // Regroup affiliated tasks together.
7512            for (int i = 0; i < N; ) {
7513                TaskRecord task = mRecentTasks.remove(i);
7514                if (mTmpRecents.contains(task)) {
7515                    continue;
7516                }
7517                int affiliatedTaskId = task.mAffiliatedTaskId;
7518                while (true) {
7519                    TaskRecord next = task.mNextAffiliate;
7520                    if (next == null) {
7521                        break;
7522                    }
7523                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7524                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7525                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7526                        task.setNextAffiliate(null);
7527                        if (next.mPrevAffiliate == task) {
7528                            next.setPrevAffiliate(null);
7529                        }
7530                        break;
7531                    }
7532                    if (next.mPrevAffiliate != task) {
7533                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7534                                next.mPrevAffiliate + " task=" + task);
7535                        next.setPrevAffiliate(null);
7536                        break;
7537                    }
7538                    if (!mRecentTasks.contains(next)) {
7539                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7540                        task.setNextAffiliate(null);
7541                        if (next.mPrevAffiliate == task) {
7542                            next.setPrevAffiliate(null);
7543                        }
7544                        break;
7545                    }
7546                    task = next;
7547                }
7548                // task is now the end of the list
7549                do {
7550                    mRecentTasks.remove(task);
7551                    mRecentTasks.add(i++, task);
7552                    mTmpRecents.add(task);
7553                } while ((task = task.mPrevAffiliate) != null);
7554            }
7555            mTmpRecents.clear();
7556            // mRecentTasks is now in sorted, affiliated order.
7557
7558            for (int i=0; i<N && maxNum > 0; i++) {
7559                TaskRecord tr = mRecentTasks.get(i);
7560                // Only add calling user or related users recent tasks
7561                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7562
7563                // Return the entry if desired by the caller.  We always return
7564                // the first entry, because callers always expect this to be the
7565                // foreground app.  We may filter others if the caller has
7566                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7567                // we should exclude the entry.
7568
7569                if (i == 0
7570                        || withExcluded
7571                        || (tr.intent == null)
7572                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7573                                == 0)) {
7574                    if (!allowed) {
7575                        // If the caller doesn't have the GET_TASKS permission, then only
7576                        // allow them to see a small subset of tasks -- their own and home.
7577                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7578                            continue;
7579                        }
7580                    }
7581                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7582                        // Don't include auto remove tasks that are finished or finishing.
7583                        continue;
7584                    }
7585
7586                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7587                    if (!detailed) {
7588                        rti.baseIntent.replaceExtras((Bundle)null);
7589                    }
7590
7591                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7592                        // Check whether this activity is currently available.
7593                        try {
7594                            if (rti.origActivity != null) {
7595                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7596                                        == null) {
7597                                    continue;
7598                                }
7599                            } else if (rti.baseIntent != null) {
7600                                if (pm.queryIntentActivities(rti.baseIntent,
7601                                        null, 0, userId) == null) {
7602                                    continue;
7603                                }
7604                            }
7605                        } catch (RemoteException e) {
7606                            // Will never happen.
7607                        }
7608                    }
7609
7610                    res.add(rti);
7611                    maxNum--;
7612                }
7613            }
7614            return res;
7615        }
7616    }
7617
7618    private TaskRecord recentTaskForIdLocked(int id) {
7619        final int N = mRecentTasks.size();
7620            for (int i=0; i<N; i++) {
7621                TaskRecord tr = mRecentTasks.get(i);
7622                if (tr.taskId == id) {
7623                    return tr;
7624                }
7625            }
7626            return null;
7627    }
7628
7629    @Override
7630    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7631        synchronized (this) {
7632            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7633                    "getTaskThumbnail()");
7634            TaskRecord tr = recentTaskForIdLocked(id);
7635            if (tr != null) {
7636                return tr.getTaskThumbnailLocked();
7637            }
7638        }
7639        return null;
7640    }
7641
7642    @Override
7643    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7644        synchronized (this) {
7645            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7646            if (r != null) {
7647                r.taskDescription = td;
7648                r.task.updateTaskDescription();
7649            }
7650        }
7651    }
7652
7653    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7654        if (!pr.killedByAm) {
7655            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7656            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7657                    pr.processName, pr.setAdj, reason);
7658            pr.killedByAm = true;
7659            Process.killProcessQuiet(pr.pid);
7660            Process.killProcessGroup(pr.info.uid, pr.pid);
7661        }
7662    }
7663
7664    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7665        tr.disposeThumbnail();
7666        mRecentTasks.remove(tr);
7667        tr.closeRecentsChain();
7668        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7669        Intent baseIntent = new Intent(
7670                tr.intent != null ? tr.intent : tr.affinityIntent);
7671        ComponentName component = baseIntent.getComponent();
7672        if (component == null) {
7673            Slog.w(TAG, "Now component for base intent of task: " + tr);
7674            return;
7675        }
7676
7677        // Find any running services associated with this app.
7678        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7679
7680        if (killProcesses) {
7681            // Find any running processes associated with this app.
7682            final String pkg = component.getPackageName();
7683            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7684            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7685            for (int i=0; i<pmap.size(); i++) {
7686                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7687                for (int j=0; j<uids.size(); j++) {
7688                    ProcessRecord proc = uids.valueAt(j);
7689                    if (proc.userId != tr.userId) {
7690                        continue;
7691                    }
7692                    if (!proc.pkgList.containsKey(pkg)) {
7693                        continue;
7694                    }
7695                    procs.add(proc);
7696                }
7697            }
7698
7699            // Kill the running processes.
7700            for (int i=0; i<procs.size(); i++) {
7701                ProcessRecord pr = procs.get(i);
7702                if (pr == mHomeProcess) {
7703                    // Don't kill the home process along with tasks from the same package.
7704                    continue;
7705                }
7706                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7707                    killUnneededProcessLocked(pr, "remove task");
7708                } else {
7709                    pr.waitingToKill = "remove task";
7710                }
7711            }
7712        }
7713    }
7714
7715    /**
7716     * Removes the task with the specified task id.
7717     *
7718     * @param taskId Identifier of the task to be removed.
7719     * @param flags Additional operational flags.  May be 0 or
7720     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7721     * @return Returns true if the given task was found and removed.
7722     */
7723    private boolean removeTaskByIdLocked(int taskId, int flags) {
7724        TaskRecord tr = recentTaskForIdLocked(taskId);
7725        if (tr != null) {
7726            tr.removeTaskActivitiesLocked();
7727            cleanUpRemovedTaskLocked(tr, flags);
7728            if (tr.isPersistable) {
7729                notifyTaskPersisterLocked(null, true);
7730            }
7731            return true;
7732        }
7733        return false;
7734    }
7735
7736    @Override
7737    public boolean removeTask(int taskId, int flags) {
7738        synchronized (this) {
7739            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7740                    "removeTask()");
7741            long ident = Binder.clearCallingIdentity();
7742            try {
7743                return removeTaskByIdLocked(taskId, flags);
7744            } finally {
7745                Binder.restoreCallingIdentity(ident);
7746            }
7747        }
7748    }
7749
7750    /**
7751     * TODO: Add mController hook
7752     */
7753    @Override
7754    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7755        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7756                "moveTaskToFront()");
7757
7758        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7759        synchronized(this) {
7760            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7761                    Binder.getCallingUid(), "Task to front")) {
7762                ActivityOptions.abort(options);
7763                return;
7764            }
7765            final long origId = Binder.clearCallingIdentity();
7766            try {
7767                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7768                if (task == null) {
7769                    return;
7770                }
7771                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7772                    mStackSupervisor.showLockTaskToast();
7773                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7774                    return;
7775                }
7776                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7777                if (prev != null && prev.isRecentsActivity()) {
7778                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7779                }
7780                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7781            } finally {
7782                Binder.restoreCallingIdentity(origId);
7783            }
7784            ActivityOptions.abort(options);
7785        }
7786    }
7787
7788    @Override
7789    public void moveTaskToBack(int taskId) {
7790        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7791                "moveTaskToBack()");
7792
7793        synchronized(this) {
7794            TaskRecord tr = recentTaskForIdLocked(taskId);
7795            if (tr != null) {
7796                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7797                ActivityStack stack = tr.stack;
7798                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7799                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7800                            Binder.getCallingUid(), "Task to back")) {
7801                        return;
7802                    }
7803                }
7804                final long origId = Binder.clearCallingIdentity();
7805                try {
7806                    stack.moveTaskToBackLocked(taskId, null);
7807                } finally {
7808                    Binder.restoreCallingIdentity(origId);
7809                }
7810            }
7811        }
7812    }
7813
7814    /**
7815     * Moves an activity, and all of the other activities within the same task, to the bottom
7816     * of the history stack.  The activity's order within the task is unchanged.
7817     *
7818     * @param token A reference to the activity we wish to move
7819     * @param nonRoot If false then this only works if the activity is the root
7820     *                of a task; if true it will work for any activity in a task.
7821     * @return Returns true if the move completed, false if not.
7822     */
7823    @Override
7824    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7825        enforceNotIsolatedCaller("moveActivityTaskToBack");
7826        synchronized(this) {
7827            final long origId = Binder.clearCallingIdentity();
7828            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7829            if (taskId >= 0) {
7830                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7831            }
7832            Binder.restoreCallingIdentity(origId);
7833        }
7834        return false;
7835    }
7836
7837    @Override
7838    public void moveTaskBackwards(int task) {
7839        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7840                "moveTaskBackwards()");
7841
7842        synchronized(this) {
7843            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7844                    Binder.getCallingUid(), "Task backwards")) {
7845                return;
7846            }
7847            final long origId = Binder.clearCallingIdentity();
7848            moveTaskBackwardsLocked(task);
7849            Binder.restoreCallingIdentity(origId);
7850        }
7851    }
7852
7853    private final void moveTaskBackwardsLocked(int task) {
7854        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7855    }
7856
7857    @Override
7858    public IBinder getHomeActivityToken() throws RemoteException {
7859        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7860                "getHomeActivityToken()");
7861        synchronized (this) {
7862            return mStackSupervisor.getHomeActivityToken();
7863        }
7864    }
7865
7866    @Override
7867    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7868            IActivityContainerCallback callback) throws RemoteException {
7869        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7870                "createActivityContainer()");
7871        synchronized (this) {
7872            if (parentActivityToken == null) {
7873                throw new IllegalArgumentException("parent token must not be null");
7874            }
7875            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7876            if (r == null) {
7877                return null;
7878            }
7879            if (callback == null) {
7880                throw new IllegalArgumentException("callback must not be null");
7881            }
7882            return mStackSupervisor.createActivityContainer(r, callback);
7883        }
7884    }
7885
7886    @Override
7887    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7888        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7889                "deleteActivityContainer()");
7890        synchronized (this) {
7891            mStackSupervisor.deleteActivityContainer(container);
7892        }
7893    }
7894
7895    @Override
7896    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7897            throws RemoteException {
7898        synchronized (this) {
7899            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7900            if (stack != null) {
7901                return stack.mActivityContainer;
7902            }
7903            return null;
7904        }
7905    }
7906
7907    @Override
7908    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7909        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7910                "moveTaskToStack()");
7911        if (stackId == HOME_STACK_ID) {
7912            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7913                    new RuntimeException("here").fillInStackTrace());
7914        }
7915        synchronized (this) {
7916            long ident = Binder.clearCallingIdentity();
7917            try {
7918                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7919                        + stackId + " toTop=" + toTop);
7920                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7921            } finally {
7922                Binder.restoreCallingIdentity(ident);
7923            }
7924        }
7925    }
7926
7927    @Override
7928    public void resizeStack(int stackBoxId, Rect bounds) {
7929        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7930                "resizeStackBox()");
7931        long ident = Binder.clearCallingIdentity();
7932        try {
7933            mWindowManager.resizeStack(stackBoxId, bounds);
7934        } finally {
7935            Binder.restoreCallingIdentity(ident);
7936        }
7937    }
7938
7939    @Override
7940    public List<StackInfo> getAllStackInfos() {
7941        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7942                "getAllStackInfos()");
7943        long ident = Binder.clearCallingIdentity();
7944        try {
7945            synchronized (this) {
7946                return mStackSupervisor.getAllStackInfosLocked();
7947            }
7948        } finally {
7949            Binder.restoreCallingIdentity(ident);
7950        }
7951    }
7952
7953    @Override
7954    public StackInfo getStackInfo(int stackId) {
7955        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7956                "getStackInfo()");
7957        long ident = Binder.clearCallingIdentity();
7958        try {
7959            synchronized (this) {
7960                return mStackSupervisor.getStackInfoLocked(stackId);
7961            }
7962        } finally {
7963            Binder.restoreCallingIdentity(ident);
7964        }
7965    }
7966
7967    @Override
7968    public boolean isInHomeStack(int taskId) {
7969        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7970                "getStackInfo()");
7971        long ident = Binder.clearCallingIdentity();
7972        try {
7973            synchronized (this) {
7974                TaskRecord tr = recentTaskForIdLocked(taskId);
7975                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7976            }
7977        } finally {
7978            Binder.restoreCallingIdentity(ident);
7979        }
7980    }
7981
7982    @Override
7983    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7984        synchronized(this) {
7985            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7986        }
7987    }
7988
7989    private boolean isLockTaskAuthorized(String pkg) {
7990        final DevicePolicyManager dpm = (DevicePolicyManager)
7991                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7992        try {
7993            int uid = mContext.getPackageManager().getPackageUid(pkg,
7994                    Binder.getCallingUserHandle().getIdentifier());
7995            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7996        } catch (NameNotFoundException e) {
7997            return false;
7998        }
7999    }
8000
8001    void startLockTaskMode(TaskRecord task) {
8002        final String pkg;
8003        synchronized (this) {
8004            pkg = task.intent.getComponent().getPackageName();
8005        }
8006        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8007        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8008            final TaskRecord taskRecord = task;
8009            mHandler.post(new Runnable() {
8010                @Override
8011                public void run() {
8012                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8013                }
8014            });
8015            return;
8016        }
8017        long ident = Binder.clearCallingIdentity();
8018        try {
8019            synchronized (this) {
8020                // Since we lost lock on task, make sure it is still there.
8021                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8022                if (task != null) {
8023                    if (!isSystemInitiated
8024                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8025                        throw new IllegalArgumentException("Invalid task, not in foreground");
8026                    }
8027                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8028                }
8029            }
8030        } finally {
8031            Binder.restoreCallingIdentity(ident);
8032        }
8033    }
8034
8035    @Override
8036    public void startLockTaskMode(int taskId) {
8037        final TaskRecord task;
8038        long ident = Binder.clearCallingIdentity();
8039        try {
8040            synchronized (this) {
8041                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8042            }
8043        } finally {
8044            Binder.restoreCallingIdentity(ident);
8045        }
8046        if (task != null) {
8047            startLockTaskMode(task);
8048        }
8049    }
8050
8051    @Override
8052    public void startLockTaskMode(IBinder token) {
8053        final TaskRecord task;
8054        long ident = Binder.clearCallingIdentity();
8055        try {
8056            synchronized (this) {
8057                final ActivityRecord r = ActivityRecord.forToken(token);
8058                if (r == null) {
8059                    return;
8060                }
8061                task = r.task;
8062            }
8063        } finally {
8064            Binder.restoreCallingIdentity(ident);
8065        }
8066        if (task != null) {
8067            startLockTaskMode(task);
8068        }
8069    }
8070
8071    @Override
8072    public void startLockTaskModeOnCurrent() throws RemoteException {
8073        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8074        ActivityRecord r = null;
8075        synchronized (this) {
8076            r = mStackSupervisor.topRunningActivityLocked();
8077        }
8078        startLockTaskMode(r.task);
8079    }
8080
8081    @Override
8082    public void stopLockTaskMode() {
8083        // Verify that the user matches the package of the intent for the TaskRecord
8084        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8085        // and stopLockTaskMode.
8086        final int callingUid = Binder.getCallingUid();
8087        if (callingUid != Process.SYSTEM_UID) {
8088            try {
8089                String pkg =
8090                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8091                int uid = mContext.getPackageManager().getPackageUid(pkg,
8092                        Binder.getCallingUserHandle().getIdentifier());
8093                if (uid != callingUid) {
8094                    throw new SecurityException("Invalid uid, expected " + uid);
8095                }
8096            } catch (NameNotFoundException e) {
8097                Log.d(TAG, "stopLockTaskMode " + e);
8098                return;
8099            }
8100        }
8101        long ident = Binder.clearCallingIdentity();
8102        try {
8103            Log.d(TAG, "stopLockTaskMode");
8104            // Stop lock task
8105            synchronized (this) {
8106                mStackSupervisor.setLockTaskModeLocked(null, false);
8107            }
8108        } finally {
8109            Binder.restoreCallingIdentity(ident);
8110        }
8111    }
8112
8113    @Override
8114    public void stopLockTaskModeOnCurrent() throws RemoteException {
8115        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8116        long ident = Binder.clearCallingIdentity();
8117        try {
8118            stopLockTaskMode();
8119        } finally {
8120            Binder.restoreCallingIdentity(ident);
8121        }
8122    }
8123
8124    @Override
8125    public boolean isInLockTaskMode() {
8126        synchronized (this) {
8127            return mStackSupervisor.isInLockTaskMode();
8128        }
8129    }
8130
8131    // =========================================================
8132    // CONTENT PROVIDERS
8133    // =========================================================
8134
8135    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8136        List<ProviderInfo> providers = null;
8137        try {
8138            providers = AppGlobals.getPackageManager().
8139                queryContentProviders(app.processName, app.uid,
8140                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8141        } catch (RemoteException ex) {
8142        }
8143        if (DEBUG_MU)
8144            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8145        int userId = app.userId;
8146        if (providers != null) {
8147            int N = providers.size();
8148            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8149            for (int i=0; i<N; i++) {
8150                ProviderInfo cpi =
8151                    (ProviderInfo)providers.get(i);
8152                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8153                        cpi.name, cpi.flags);
8154                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8155                    // This is a singleton provider, but a user besides the
8156                    // default user is asking to initialize a process it runs
8157                    // in...  well, no, it doesn't actually run in this process,
8158                    // it runs in the process of the default user.  Get rid of it.
8159                    providers.remove(i);
8160                    N--;
8161                    i--;
8162                    continue;
8163                }
8164
8165                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8166                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8167                if (cpr == null) {
8168                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8169                    mProviderMap.putProviderByClass(comp, cpr);
8170                }
8171                if (DEBUG_MU)
8172                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8173                app.pubProviders.put(cpi.name, cpr);
8174                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8175                    // Don't add this if it is a platform component that is marked
8176                    // to run in multiple processes, because this is actually
8177                    // part of the framework so doesn't make sense to track as a
8178                    // separate apk in the process.
8179                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8180                            mProcessStats);
8181                }
8182                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8183            }
8184        }
8185        return providers;
8186    }
8187
8188    /**
8189     * Check if {@link ProcessRecord} has a possible chance at accessing the
8190     * given {@link ProviderInfo}. Final permission checking is always done
8191     * in {@link ContentProvider}.
8192     */
8193    private final String checkContentProviderPermissionLocked(
8194            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8195        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8196        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8197        boolean checkedGrants = false;
8198        if (checkUser) {
8199            // Looking for cross-user grants before enforcing the typical cross-users permissions
8200            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8201            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8202                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8203                    return null;
8204                }
8205                checkedGrants = true;
8206            }
8207            userId = handleIncomingUser(callingPid, callingUid, userId,
8208                    false, ALLOW_NON_FULL,
8209                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8210            if (userId != tmpTargetUserId) {
8211                // When we actually went to determine the final targer user ID, this ended
8212                // up different than our initial check for the authority.  This is because
8213                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8214                // SELF.  So we need to re-check the grants again.
8215                checkedGrants = false;
8216            }
8217        }
8218        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8219                cpi.applicationInfo.uid, cpi.exported)
8220                == PackageManager.PERMISSION_GRANTED) {
8221            return null;
8222        }
8223        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8224                cpi.applicationInfo.uid, cpi.exported)
8225                == PackageManager.PERMISSION_GRANTED) {
8226            return null;
8227        }
8228
8229        PathPermission[] pps = cpi.pathPermissions;
8230        if (pps != null) {
8231            int i = pps.length;
8232            while (i > 0) {
8233                i--;
8234                PathPermission pp = pps[i];
8235                String pprperm = pp.getReadPermission();
8236                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8237                        cpi.applicationInfo.uid, cpi.exported)
8238                        == PackageManager.PERMISSION_GRANTED) {
8239                    return null;
8240                }
8241                String ppwperm = pp.getWritePermission();
8242                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8243                        cpi.applicationInfo.uid, cpi.exported)
8244                        == PackageManager.PERMISSION_GRANTED) {
8245                    return null;
8246                }
8247            }
8248        }
8249        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8250            return null;
8251        }
8252
8253        String msg;
8254        if (!cpi.exported) {
8255            msg = "Permission Denial: opening provider " + cpi.name
8256                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8257                    + ", uid=" + callingUid + ") that is not exported from uid "
8258                    + cpi.applicationInfo.uid;
8259        } else {
8260            msg = "Permission Denial: opening provider " + cpi.name
8261                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8262                    + ", uid=" + callingUid + ") requires "
8263                    + cpi.readPermission + " or " + cpi.writePermission;
8264        }
8265        Slog.w(TAG, msg);
8266        return msg;
8267    }
8268
8269    /**
8270     * Returns if the ContentProvider has granted a uri to callingUid
8271     */
8272    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8273        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8274        if (perms != null) {
8275            for (int i=perms.size()-1; i>=0; i--) {
8276                GrantUri grantUri = perms.keyAt(i);
8277                if (grantUri.sourceUserId == userId || !checkUser) {
8278                    if (matchesProvider(grantUri.uri, cpi)) {
8279                        return true;
8280                    }
8281                }
8282            }
8283        }
8284        return false;
8285    }
8286
8287    /**
8288     * Returns true if the uri authority is one of the authorities specified in the provider.
8289     */
8290    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8291        String uriAuth = uri.getAuthority();
8292        String cpiAuth = cpi.authority;
8293        if (cpiAuth.indexOf(';') == -1) {
8294            return cpiAuth.equals(uriAuth);
8295        }
8296        String[] cpiAuths = cpiAuth.split(";");
8297        int length = cpiAuths.length;
8298        for (int i = 0; i < length; i++) {
8299            if (cpiAuths[i].equals(uriAuth)) return true;
8300        }
8301        return false;
8302    }
8303
8304    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8305            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8306        if (r != null) {
8307            for (int i=0; i<r.conProviders.size(); i++) {
8308                ContentProviderConnection conn = r.conProviders.get(i);
8309                if (conn.provider == cpr) {
8310                    if (DEBUG_PROVIDER) Slog.v(TAG,
8311                            "Adding provider requested by "
8312                            + r.processName + " from process "
8313                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8314                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8315                    if (stable) {
8316                        conn.stableCount++;
8317                        conn.numStableIncs++;
8318                    } else {
8319                        conn.unstableCount++;
8320                        conn.numUnstableIncs++;
8321                    }
8322                    return conn;
8323                }
8324            }
8325            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8326            if (stable) {
8327                conn.stableCount = 1;
8328                conn.numStableIncs = 1;
8329            } else {
8330                conn.unstableCount = 1;
8331                conn.numUnstableIncs = 1;
8332            }
8333            cpr.connections.add(conn);
8334            r.conProviders.add(conn);
8335            return conn;
8336        }
8337        cpr.addExternalProcessHandleLocked(externalProcessToken);
8338        return null;
8339    }
8340
8341    boolean decProviderCountLocked(ContentProviderConnection conn,
8342            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8343        if (conn != null) {
8344            cpr = conn.provider;
8345            if (DEBUG_PROVIDER) Slog.v(TAG,
8346                    "Removing provider requested by "
8347                    + conn.client.processName + " from process "
8348                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8349                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8350            if (stable) {
8351                conn.stableCount--;
8352            } else {
8353                conn.unstableCount--;
8354            }
8355            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8356                cpr.connections.remove(conn);
8357                conn.client.conProviders.remove(conn);
8358                return true;
8359            }
8360            return false;
8361        }
8362        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8363        return false;
8364    }
8365
8366    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8367            String name, IBinder token, boolean stable, int userId) {
8368        ContentProviderRecord cpr;
8369        ContentProviderConnection conn = null;
8370        ProviderInfo cpi = null;
8371
8372        synchronized(this) {
8373            ProcessRecord r = null;
8374            if (caller != null) {
8375                r = getRecordForAppLocked(caller);
8376                if (r == null) {
8377                    throw new SecurityException(
8378                            "Unable to find app for caller " + caller
8379                          + " (pid=" + Binder.getCallingPid()
8380                          + ") when getting content provider " + name);
8381                }
8382            }
8383
8384            boolean checkCrossUser = true;
8385
8386            // First check if this content provider has been published...
8387            cpr = mProviderMap.getProviderByName(name, userId);
8388            // If that didn't work, check if it exists for user 0 and then
8389            // verify that it's a singleton provider before using it.
8390            if (cpr == null && userId != UserHandle.USER_OWNER) {
8391                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8392                if (cpr != null) {
8393                    cpi = cpr.info;
8394                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8395                            cpi.name, cpi.flags)
8396                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8397                        userId = UserHandle.USER_OWNER;
8398                        checkCrossUser = false;
8399                    } else {
8400                        cpr = null;
8401                        cpi = null;
8402                    }
8403                }
8404            }
8405
8406            boolean providerRunning = cpr != null;
8407            if (providerRunning) {
8408                cpi = cpr.info;
8409                String msg;
8410                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8411                        != null) {
8412                    throw new SecurityException(msg);
8413                }
8414
8415                if (r != null && cpr.canRunHere(r)) {
8416                    // This provider has been published or is in the process
8417                    // of being published...  but it is also allowed to run
8418                    // in the caller's process, so don't make a connection
8419                    // and just let the caller instantiate its own instance.
8420                    ContentProviderHolder holder = cpr.newHolder(null);
8421                    // don't give caller the provider object, it needs
8422                    // to make its own.
8423                    holder.provider = null;
8424                    return holder;
8425                }
8426
8427                final long origId = Binder.clearCallingIdentity();
8428
8429                // In this case the provider instance already exists, so we can
8430                // return it right away.
8431                conn = incProviderCountLocked(r, cpr, token, stable);
8432                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8433                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8434                        // If this is a perceptible app accessing the provider,
8435                        // make sure to count it as being accessed and thus
8436                        // back up on the LRU list.  This is good because
8437                        // content providers are often expensive to start.
8438                        updateLruProcessLocked(cpr.proc, false, null);
8439                    }
8440                }
8441
8442                if (cpr.proc != null) {
8443                    if (false) {
8444                        if (cpr.name.flattenToShortString().equals(
8445                                "com.android.providers.calendar/.CalendarProvider2")) {
8446                            Slog.v(TAG, "****************** KILLING "
8447                                + cpr.name.flattenToShortString());
8448                            Process.killProcess(cpr.proc.pid);
8449                        }
8450                    }
8451                    boolean success = updateOomAdjLocked(cpr.proc);
8452                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8453                    // NOTE: there is still a race here where a signal could be
8454                    // pending on the process even though we managed to update its
8455                    // adj level.  Not sure what to do about this, but at least
8456                    // the race is now smaller.
8457                    if (!success) {
8458                        // Uh oh...  it looks like the provider's process
8459                        // has been killed on us.  We need to wait for a new
8460                        // process to be started, and make sure its death
8461                        // doesn't kill our process.
8462                        Slog.i(TAG,
8463                                "Existing provider " + cpr.name.flattenToShortString()
8464                                + " is crashing; detaching " + r);
8465                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8466                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8467                        if (!lastRef) {
8468                            // This wasn't the last ref our process had on
8469                            // the provider...  we have now been killed, bail.
8470                            return null;
8471                        }
8472                        providerRunning = false;
8473                        conn = null;
8474                    }
8475                }
8476
8477                Binder.restoreCallingIdentity(origId);
8478            }
8479
8480            boolean singleton;
8481            if (!providerRunning) {
8482                try {
8483                    cpi = AppGlobals.getPackageManager().
8484                        resolveContentProvider(name,
8485                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8486                } catch (RemoteException ex) {
8487                }
8488                if (cpi == null) {
8489                    return null;
8490                }
8491                // If the provider is a singleton AND
8492                // (it's a call within the same user || the provider is a
8493                // privileged app)
8494                // Then allow connecting to the singleton provider
8495                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8496                        cpi.name, cpi.flags)
8497                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8498                if (singleton) {
8499                    userId = UserHandle.USER_OWNER;
8500                }
8501                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8502
8503                String msg;
8504                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8505                        != null) {
8506                    throw new SecurityException(msg);
8507                }
8508
8509                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8510                        && !cpi.processName.equals("system")) {
8511                    // If this content provider does not run in the system
8512                    // process, and the system is not yet ready to run other
8513                    // processes, then fail fast instead of hanging.
8514                    throw new IllegalArgumentException(
8515                            "Attempt to launch content provider before system ready");
8516                }
8517
8518                // Make sure that the user who owns this provider is started.  If not,
8519                // we don't want to allow it to run.
8520                if (mStartedUsers.get(userId) == null) {
8521                    Slog.w(TAG, "Unable to launch app "
8522                            + cpi.applicationInfo.packageName + "/"
8523                            + cpi.applicationInfo.uid + " for provider "
8524                            + name + ": user " + userId + " is stopped");
8525                    return null;
8526                }
8527
8528                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8529                cpr = mProviderMap.getProviderByClass(comp, userId);
8530                final boolean firstClass = cpr == null;
8531                if (firstClass) {
8532                    try {
8533                        ApplicationInfo ai =
8534                            AppGlobals.getPackageManager().
8535                                getApplicationInfo(
8536                                        cpi.applicationInfo.packageName,
8537                                        STOCK_PM_FLAGS, userId);
8538                        if (ai == null) {
8539                            Slog.w(TAG, "No package info for content provider "
8540                                    + cpi.name);
8541                            return null;
8542                        }
8543                        ai = getAppInfoForUser(ai, userId);
8544                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8545                    } catch (RemoteException ex) {
8546                        // pm is in same process, this will never happen.
8547                    }
8548                }
8549
8550                if (r != null && cpr.canRunHere(r)) {
8551                    // If this is a multiprocess provider, then just return its
8552                    // info and allow the caller to instantiate it.  Only do
8553                    // this if the provider is the same user as the caller's
8554                    // process, or can run as root (so can be in any process).
8555                    return cpr.newHolder(null);
8556                }
8557
8558                if (DEBUG_PROVIDER) {
8559                    RuntimeException e = new RuntimeException("here");
8560                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8561                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8562                }
8563
8564                // This is single process, and our app is now connecting to it.
8565                // See if we are already in the process of launching this
8566                // provider.
8567                final int N = mLaunchingProviders.size();
8568                int i;
8569                for (i=0; i<N; i++) {
8570                    if (mLaunchingProviders.get(i) == cpr) {
8571                        break;
8572                    }
8573                }
8574
8575                // If the provider is not already being launched, then get it
8576                // started.
8577                if (i >= N) {
8578                    final long origId = Binder.clearCallingIdentity();
8579
8580                    try {
8581                        // Content provider is now in use, its package can't be stopped.
8582                        try {
8583                            AppGlobals.getPackageManager().setPackageStoppedState(
8584                                    cpr.appInfo.packageName, false, userId);
8585                        } catch (RemoteException e) {
8586                        } catch (IllegalArgumentException e) {
8587                            Slog.w(TAG, "Failed trying to unstop package "
8588                                    + cpr.appInfo.packageName + ": " + e);
8589                        }
8590
8591                        // Use existing process if already started
8592                        ProcessRecord proc = getProcessRecordLocked(
8593                                cpi.processName, cpr.appInfo.uid, false);
8594                        if (proc != null && proc.thread != null) {
8595                            if (DEBUG_PROVIDER) {
8596                                Slog.d(TAG, "Installing in existing process " + proc);
8597                            }
8598                            proc.pubProviders.put(cpi.name, cpr);
8599                            try {
8600                                proc.thread.scheduleInstallProvider(cpi);
8601                            } catch (RemoteException e) {
8602                            }
8603                        } else {
8604                            proc = startProcessLocked(cpi.processName,
8605                                    cpr.appInfo, false, 0, "content provider",
8606                                    new ComponentName(cpi.applicationInfo.packageName,
8607                                            cpi.name), false, false, false);
8608                            if (proc == null) {
8609                                Slog.w(TAG, "Unable to launch app "
8610                                        + cpi.applicationInfo.packageName + "/"
8611                                        + cpi.applicationInfo.uid + " for provider "
8612                                        + name + ": process is bad");
8613                                return null;
8614                            }
8615                        }
8616                        cpr.launchingApp = proc;
8617                        mLaunchingProviders.add(cpr);
8618                    } finally {
8619                        Binder.restoreCallingIdentity(origId);
8620                    }
8621                }
8622
8623                // Make sure the provider is published (the same provider class
8624                // may be published under multiple names).
8625                if (firstClass) {
8626                    mProviderMap.putProviderByClass(comp, cpr);
8627                }
8628
8629                mProviderMap.putProviderByName(name, cpr);
8630                conn = incProviderCountLocked(r, cpr, token, stable);
8631                if (conn != null) {
8632                    conn.waiting = true;
8633                }
8634            }
8635        }
8636
8637        // Wait for the provider to be published...
8638        synchronized (cpr) {
8639            while (cpr.provider == null) {
8640                if (cpr.launchingApp == null) {
8641                    Slog.w(TAG, "Unable to launch app "
8642                            + cpi.applicationInfo.packageName + "/"
8643                            + cpi.applicationInfo.uid + " for provider "
8644                            + name + ": launching app became null");
8645                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8646                            UserHandle.getUserId(cpi.applicationInfo.uid),
8647                            cpi.applicationInfo.packageName,
8648                            cpi.applicationInfo.uid, name);
8649                    return null;
8650                }
8651                try {
8652                    if (DEBUG_MU) {
8653                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8654                                + cpr.launchingApp);
8655                    }
8656                    if (conn != null) {
8657                        conn.waiting = true;
8658                    }
8659                    cpr.wait();
8660                } catch (InterruptedException ex) {
8661                } finally {
8662                    if (conn != null) {
8663                        conn.waiting = false;
8664                    }
8665                }
8666            }
8667        }
8668        return cpr != null ? cpr.newHolder(conn) : null;
8669    }
8670
8671    @Override
8672    public final ContentProviderHolder getContentProvider(
8673            IApplicationThread caller, String name, int userId, boolean stable) {
8674        enforceNotIsolatedCaller("getContentProvider");
8675        if (caller == null) {
8676            String msg = "null IApplicationThread when getting content provider "
8677                    + name;
8678            Slog.w(TAG, msg);
8679            throw new SecurityException(msg);
8680        }
8681        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8682        // with cross-user grant.
8683        return getContentProviderImpl(caller, name, null, stable, userId);
8684    }
8685
8686    public ContentProviderHolder getContentProviderExternal(
8687            String name, int userId, IBinder token) {
8688        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8689            "Do not have permission in call getContentProviderExternal()");
8690        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8691                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8692        return getContentProviderExternalUnchecked(name, token, userId);
8693    }
8694
8695    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8696            IBinder token, int userId) {
8697        return getContentProviderImpl(null, name, token, true, userId);
8698    }
8699
8700    /**
8701     * Drop a content provider from a ProcessRecord's bookkeeping
8702     */
8703    public void removeContentProvider(IBinder connection, boolean stable) {
8704        enforceNotIsolatedCaller("removeContentProvider");
8705        long ident = Binder.clearCallingIdentity();
8706        try {
8707            synchronized (this) {
8708                ContentProviderConnection conn;
8709                try {
8710                    conn = (ContentProviderConnection)connection;
8711                } catch (ClassCastException e) {
8712                    String msg ="removeContentProvider: " + connection
8713                            + " not a ContentProviderConnection";
8714                    Slog.w(TAG, msg);
8715                    throw new IllegalArgumentException(msg);
8716                }
8717                if (conn == null) {
8718                    throw new NullPointerException("connection is null");
8719                }
8720                if (decProviderCountLocked(conn, null, null, stable)) {
8721                    updateOomAdjLocked();
8722                }
8723            }
8724        } finally {
8725            Binder.restoreCallingIdentity(ident);
8726        }
8727    }
8728
8729    public void removeContentProviderExternal(String name, IBinder token) {
8730        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8731            "Do not have permission in call removeContentProviderExternal()");
8732        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8733    }
8734
8735    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8736        synchronized (this) {
8737            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8738            if(cpr == null) {
8739                //remove from mProvidersByClass
8740                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8741                return;
8742            }
8743
8744            //update content provider record entry info
8745            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8746            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8747            if (localCpr.hasExternalProcessHandles()) {
8748                if (localCpr.removeExternalProcessHandleLocked(token)) {
8749                    updateOomAdjLocked();
8750                } else {
8751                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8752                            + " with no external reference for token: "
8753                            + token + ".");
8754                }
8755            } else {
8756                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8757                        + " with no external references.");
8758            }
8759        }
8760    }
8761
8762    public final void publishContentProviders(IApplicationThread caller,
8763            List<ContentProviderHolder> providers) {
8764        if (providers == null) {
8765            return;
8766        }
8767
8768        enforceNotIsolatedCaller("publishContentProviders");
8769        synchronized (this) {
8770            final ProcessRecord r = getRecordForAppLocked(caller);
8771            if (DEBUG_MU)
8772                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8773            if (r == null) {
8774                throw new SecurityException(
8775                        "Unable to find app for caller " + caller
8776                      + " (pid=" + Binder.getCallingPid()
8777                      + ") when publishing content providers");
8778            }
8779
8780            final long origId = Binder.clearCallingIdentity();
8781
8782            final int N = providers.size();
8783            for (int i=0; i<N; i++) {
8784                ContentProviderHolder src = providers.get(i);
8785                if (src == null || src.info == null || src.provider == null) {
8786                    continue;
8787                }
8788                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8789                if (DEBUG_MU)
8790                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8791                if (dst != null) {
8792                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8793                    mProviderMap.putProviderByClass(comp, dst);
8794                    String names[] = dst.info.authority.split(";");
8795                    for (int j = 0; j < names.length; j++) {
8796                        mProviderMap.putProviderByName(names[j], dst);
8797                    }
8798
8799                    int NL = mLaunchingProviders.size();
8800                    int j;
8801                    for (j=0; j<NL; j++) {
8802                        if (mLaunchingProviders.get(j) == dst) {
8803                            mLaunchingProviders.remove(j);
8804                            j--;
8805                            NL--;
8806                        }
8807                    }
8808                    synchronized (dst) {
8809                        dst.provider = src.provider;
8810                        dst.proc = r;
8811                        dst.notifyAll();
8812                    }
8813                    updateOomAdjLocked(r);
8814                }
8815            }
8816
8817            Binder.restoreCallingIdentity(origId);
8818        }
8819    }
8820
8821    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8822        ContentProviderConnection conn;
8823        try {
8824            conn = (ContentProviderConnection)connection;
8825        } catch (ClassCastException e) {
8826            String msg ="refContentProvider: " + connection
8827                    + " not a ContentProviderConnection";
8828            Slog.w(TAG, msg);
8829            throw new IllegalArgumentException(msg);
8830        }
8831        if (conn == null) {
8832            throw new NullPointerException("connection is null");
8833        }
8834
8835        synchronized (this) {
8836            if (stable > 0) {
8837                conn.numStableIncs += stable;
8838            }
8839            stable = conn.stableCount + stable;
8840            if (stable < 0) {
8841                throw new IllegalStateException("stableCount < 0: " + stable);
8842            }
8843
8844            if (unstable > 0) {
8845                conn.numUnstableIncs += unstable;
8846            }
8847            unstable = conn.unstableCount + unstable;
8848            if (unstable < 0) {
8849                throw new IllegalStateException("unstableCount < 0: " + unstable);
8850            }
8851
8852            if ((stable+unstable) <= 0) {
8853                throw new IllegalStateException("ref counts can't go to zero here: stable="
8854                        + stable + " unstable=" + unstable);
8855            }
8856            conn.stableCount = stable;
8857            conn.unstableCount = unstable;
8858            return !conn.dead;
8859        }
8860    }
8861
8862    public void unstableProviderDied(IBinder connection) {
8863        ContentProviderConnection conn;
8864        try {
8865            conn = (ContentProviderConnection)connection;
8866        } catch (ClassCastException e) {
8867            String msg ="refContentProvider: " + connection
8868                    + " not a ContentProviderConnection";
8869            Slog.w(TAG, msg);
8870            throw new IllegalArgumentException(msg);
8871        }
8872        if (conn == null) {
8873            throw new NullPointerException("connection is null");
8874        }
8875
8876        // Safely retrieve the content provider associated with the connection.
8877        IContentProvider provider;
8878        synchronized (this) {
8879            provider = conn.provider.provider;
8880        }
8881
8882        if (provider == null) {
8883            // Um, yeah, we're way ahead of you.
8884            return;
8885        }
8886
8887        // Make sure the caller is being honest with us.
8888        if (provider.asBinder().pingBinder()) {
8889            // Er, no, still looks good to us.
8890            synchronized (this) {
8891                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8892                        + " says " + conn + " died, but we don't agree");
8893                return;
8894            }
8895        }
8896
8897        // Well look at that!  It's dead!
8898        synchronized (this) {
8899            if (conn.provider.provider != provider) {
8900                // But something changed...  good enough.
8901                return;
8902            }
8903
8904            ProcessRecord proc = conn.provider.proc;
8905            if (proc == null || proc.thread == null) {
8906                // Seems like the process is already cleaned up.
8907                return;
8908            }
8909
8910            // As far as we're concerned, this is just like receiving a
8911            // death notification...  just a bit prematurely.
8912            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8913                    + ") early provider death");
8914            final long ident = Binder.clearCallingIdentity();
8915            try {
8916                appDiedLocked(proc, proc.pid, proc.thread);
8917            } finally {
8918                Binder.restoreCallingIdentity(ident);
8919            }
8920        }
8921    }
8922
8923    @Override
8924    public void appNotRespondingViaProvider(IBinder connection) {
8925        enforceCallingPermission(
8926                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8927
8928        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8929        if (conn == null) {
8930            Slog.w(TAG, "ContentProviderConnection is null");
8931            return;
8932        }
8933
8934        final ProcessRecord host = conn.provider.proc;
8935        if (host == null) {
8936            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8937            return;
8938        }
8939
8940        final long token = Binder.clearCallingIdentity();
8941        try {
8942            appNotResponding(host, null, null, false, "ContentProvider not responding");
8943        } finally {
8944            Binder.restoreCallingIdentity(token);
8945        }
8946    }
8947
8948    public final void installSystemProviders() {
8949        List<ProviderInfo> providers;
8950        synchronized (this) {
8951            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8952            providers = generateApplicationProvidersLocked(app);
8953            if (providers != null) {
8954                for (int i=providers.size()-1; i>=0; i--) {
8955                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8956                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8957                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8958                                + ": not system .apk");
8959                        providers.remove(i);
8960                    }
8961                }
8962            }
8963        }
8964        if (providers != null) {
8965            mSystemThread.installSystemProviders(providers);
8966        }
8967
8968        mCoreSettingsObserver = new CoreSettingsObserver(this);
8969
8970        //mUsageStatsService.monitorPackages();
8971    }
8972
8973    /**
8974     * Allows apps to retrieve the MIME type of a URI.
8975     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
8976     * users, then it does not need permission to access the ContentProvider.
8977     * Either, it needs cross-user uri grants.
8978     *
8979     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8980     *
8981     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8982     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8983     */
8984    public String getProviderMimeType(Uri uri, int userId) {
8985        enforceNotIsolatedCaller("getProviderMimeType");
8986        final String name = uri.getAuthority();
8987        int callingUid = Binder.getCallingUid();
8988        int callingPid = Binder.getCallingPid();
8989        long ident = 0;
8990        boolean clearedIdentity = false;
8991        userId = unsafeConvertIncomingUser(userId);
8992        if (UserHandle.getUserId(callingUid) != userId) {
8993            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
8994                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
8995                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
8996                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
8997                clearedIdentity = true;
8998                ident = Binder.clearCallingIdentity();
8999            }
9000        }
9001        ContentProviderHolder holder = null;
9002        try {
9003            holder = getContentProviderExternalUnchecked(name, null, userId);
9004            if (holder != null) {
9005                return holder.provider.getType(uri);
9006            }
9007        } catch (RemoteException e) {
9008            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9009            return null;
9010        } finally {
9011            // We need to clear the identity to call removeContentProviderExternalUnchecked
9012            if (!clearedIdentity) {
9013                ident = Binder.clearCallingIdentity();
9014            }
9015            try {
9016                if (holder != null) {
9017                    removeContentProviderExternalUnchecked(name, null, userId);
9018                }
9019            } finally {
9020                Binder.restoreCallingIdentity(ident);
9021            }
9022        }
9023
9024        return null;
9025    }
9026
9027    // =========================================================
9028    // GLOBAL MANAGEMENT
9029    // =========================================================
9030
9031    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9032            boolean isolated, int isolatedUid) {
9033        String proc = customProcess != null ? customProcess : info.processName;
9034        BatteryStatsImpl.Uid.Proc ps = null;
9035        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9036        int uid = info.uid;
9037        if (isolated) {
9038            if (isolatedUid == 0) {
9039                int userId = UserHandle.getUserId(uid);
9040                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9041                while (true) {
9042                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9043                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9044                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9045                    }
9046                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9047                    mNextIsolatedProcessUid++;
9048                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9049                        // No process for this uid, use it.
9050                        break;
9051                    }
9052                    stepsLeft--;
9053                    if (stepsLeft <= 0) {
9054                        return null;
9055                    }
9056                }
9057            } else {
9058                // Special case for startIsolatedProcess (internal only), where
9059                // the uid of the isolated process is specified by the caller.
9060                uid = isolatedUid;
9061            }
9062        }
9063        return new ProcessRecord(stats, info, proc, uid);
9064    }
9065
9066    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9067            String abiOverride) {
9068        ProcessRecord app;
9069        if (!isolated) {
9070            app = getProcessRecordLocked(info.processName, info.uid, true);
9071        } else {
9072            app = null;
9073        }
9074
9075        if (app == null) {
9076            app = newProcessRecordLocked(info, null, isolated, 0);
9077            mProcessNames.put(info.processName, app.uid, app);
9078            if (isolated) {
9079                mIsolatedProcesses.put(app.uid, app);
9080            }
9081            updateLruProcessLocked(app, false, null);
9082            updateOomAdjLocked();
9083        }
9084
9085        // This package really, really can not be stopped.
9086        try {
9087            AppGlobals.getPackageManager().setPackageStoppedState(
9088                    info.packageName, false, UserHandle.getUserId(app.uid));
9089        } catch (RemoteException e) {
9090        } catch (IllegalArgumentException e) {
9091            Slog.w(TAG, "Failed trying to unstop package "
9092                    + info.packageName + ": " + e);
9093        }
9094
9095        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9096                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9097            app.persistent = true;
9098            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9099        }
9100        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9101            mPersistentStartingProcesses.add(app);
9102            startProcessLocked(app, "added application", app.processName, abiOverride,
9103                    null /* entryPoint */, null /* entryPointArgs */);
9104        }
9105
9106        return app;
9107    }
9108
9109    public void unhandledBack() {
9110        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9111                "unhandledBack()");
9112
9113        synchronized(this) {
9114            final long origId = Binder.clearCallingIdentity();
9115            try {
9116                getFocusedStack().unhandledBackLocked();
9117            } finally {
9118                Binder.restoreCallingIdentity(origId);
9119            }
9120        }
9121    }
9122
9123    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9124        enforceNotIsolatedCaller("openContentUri");
9125        final int userId = UserHandle.getCallingUserId();
9126        String name = uri.getAuthority();
9127        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9128        ParcelFileDescriptor pfd = null;
9129        if (cph != null) {
9130            // We record the binder invoker's uid in thread-local storage before
9131            // going to the content provider to open the file.  Later, in the code
9132            // that handles all permissions checks, we look for this uid and use
9133            // that rather than the Activity Manager's own uid.  The effect is that
9134            // we do the check against the caller's permissions even though it looks
9135            // to the content provider like the Activity Manager itself is making
9136            // the request.
9137            sCallerIdentity.set(new Identity(
9138                    Binder.getCallingPid(), Binder.getCallingUid()));
9139            try {
9140                pfd = cph.provider.openFile(null, uri, "r", null);
9141            } catch (FileNotFoundException e) {
9142                // do nothing; pfd will be returned null
9143            } finally {
9144                // Ensure that whatever happens, we clean up the identity state
9145                sCallerIdentity.remove();
9146            }
9147
9148            // We've got the fd now, so we're done with the provider.
9149            removeContentProviderExternalUnchecked(name, null, userId);
9150        } else {
9151            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9152        }
9153        return pfd;
9154    }
9155
9156    // Actually is sleeping or shutting down or whatever else in the future
9157    // is an inactive state.
9158    public boolean isSleepingOrShuttingDown() {
9159        return mSleeping || mShuttingDown;
9160    }
9161
9162    public boolean isSleeping() {
9163        return mSleeping;
9164    }
9165
9166    void goingToSleep() {
9167        synchronized(this) {
9168            mWentToSleep = true;
9169            updateEventDispatchingLocked();
9170            goToSleepIfNeededLocked();
9171        }
9172    }
9173
9174    void finishRunningVoiceLocked() {
9175        if (mRunningVoice) {
9176            mRunningVoice = false;
9177            goToSleepIfNeededLocked();
9178        }
9179    }
9180
9181    void goToSleepIfNeededLocked() {
9182        if (mWentToSleep && !mRunningVoice) {
9183            if (!mSleeping) {
9184                mSleeping = true;
9185                mStackSupervisor.goingToSleepLocked();
9186
9187                // Initialize the wake times of all processes.
9188                checkExcessivePowerUsageLocked(false);
9189                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9190                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9191                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9192            }
9193        }
9194    }
9195
9196    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9197        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9198            // Never persist the home stack.
9199            return;
9200        }
9201        mTaskPersister.wakeup(task, flush);
9202    }
9203
9204    @Override
9205    public boolean shutdown(int timeout) {
9206        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9207                != PackageManager.PERMISSION_GRANTED) {
9208            throw new SecurityException("Requires permission "
9209                    + android.Manifest.permission.SHUTDOWN);
9210        }
9211
9212        boolean timedout = false;
9213
9214        synchronized(this) {
9215            mShuttingDown = true;
9216            updateEventDispatchingLocked();
9217            timedout = mStackSupervisor.shutdownLocked(timeout);
9218        }
9219
9220        mAppOpsService.shutdown();
9221        if (mUsageStatsService != null) {
9222            mUsageStatsService.prepareShutdown();
9223        }
9224        mBatteryStatsService.shutdown();
9225        synchronized (this) {
9226            mProcessStats.shutdownLocked();
9227        }
9228        notifyTaskPersisterLocked(null, true);
9229
9230        return timedout;
9231    }
9232
9233    public final void activitySlept(IBinder token) {
9234        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9235
9236        final long origId = Binder.clearCallingIdentity();
9237
9238        synchronized (this) {
9239            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9240            if (r != null) {
9241                mStackSupervisor.activitySleptLocked(r);
9242            }
9243        }
9244
9245        Binder.restoreCallingIdentity(origId);
9246    }
9247
9248    void logLockScreen(String msg) {
9249        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9250                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9251                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9252                mStackSupervisor.mDismissKeyguardOnNextActivity);
9253    }
9254
9255    private void comeOutOfSleepIfNeededLocked() {
9256        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9257            if (mSleeping) {
9258                mSleeping = false;
9259                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9260            }
9261        }
9262    }
9263
9264    void wakingUp() {
9265        synchronized(this) {
9266            mWentToSleep = false;
9267            updateEventDispatchingLocked();
9268            comeOutOfSleepIfNeededLocked();
9269        }
9270    }
9271
9272    void startRunningVoiceLocked() {
9273        if (!mRunningVoice) {
9274            mRunningVoice = true;
9275            comeOutOfSleepIfNeededLocked();
9276        }
9277    }
9278
9279    private void updateEventDispatchingLocked() {
9280        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9281    }
9282
9283    public void setLockScreenShown(boolean shown) {
9284        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9285                != PackageManager.PERMISSION_GRANTED) {
9286            throw new SecurityException("Requires permission "
9287                    + android.Manifest.permission.DEVICE_POWER);
9288        }
9289
9290        synchronized(this) {
9291            long ident = Binder.clearCallingIdentity();
9292            try {
9293                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9294                mLockScreenShown = shown;
9295                comeOutOfSleepIfNeededLocked();
9296            } finally {
9297                Binder.restoreCallingIdentity(ident);
9298            }
9299        }
9300    }
9301
9302    @Override
9303    public void stopAppSwitches() {
9304        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9305                != PackageManager.PERMISSION_GRANTED) {
9306            throw new SecurityException("Requires permission "
9307                    + android.Manifest.permission.STOP_APP_SWITCHES);
9308        }
9309
9310        synchronized(this) {
9311            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9312                    + APP_SWITCH_DELAY_TIME;
9313            mDidAppSwitch = false;
9314            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9315            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9316            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9317        }
9318    }
9319
9320    public void resumeAppSwitches() {
9321        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9322                != PackageManager.PERMISSION_GRANTED) {
9323            throw new SecurityException("Requires permission "
9324                    + android.Manifest.permission.STOP_APP_SWITCHES);
9325        }
9326
9327        synchronized(this) {
9328            // Note that we don't execute any pending app switches... we will
9329            // let those wait until either the timeout, or the next start
9330            // activity request.
9331            mAppSwitchesAllowedTime = 0;
9332        }
9333    }
9334
9335    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9336            String name) {
9337        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9338            return true;
9339        }
9340
9341        final int perm = checkComponentPermission(
9342                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9343                callingUid, -1, true);
9344        if (perm == PackageManager.PERMISSION_GRANTED) {
9345            return true;
9346        }
9347
9348        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9349        return false;
9350    }
9351
9352    public void setDebugApp(String packageName, boolean waitForDebugger,
9353            boolean persistent) {
9354        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9355                "setDebugApp()");
9356
9357        long ident = Binder.clearCallingIdentity();
9358        try {
9359            // Note that this is not really thread safe if there are multiple
9360            // callers into it at the same time, but that's not a situation we
9361            // care about.
9362            if (persistent) {
9363                final ContentResolver resolver = mContext.getContentResolver();
9364                Settings.Global.putString(
9365                    resolver, Settings.Global.DEBUG_APP,
9366                    packageName);
9367                Settings.Global.putInt(
9368                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9369                    waitForDebugger ? 1 : 0);
9370            }
9371
9372            synchronized (this) {
9373                if (!persistent) {
9374                    mOrigDebugApp = mDebugApp;
9375                    mOrigWaitForDebugger = mWaitForDebugger;
9376                }
9377                mDebugApp = packageName;
9378                mWaitForDebugger = waitForDebugger;
9379                mDebugTransient = !persistent;
9380                if (packageName != null) {
9381                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9382                            false, UserHandle.USER_ALL, "set debug app");
9383                }
9384            }
9385        } finally {
9386            Binder.restoreCallingIdentity(ident);
9387        }
9388    }
9389
9390    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9391        synchronized (this) {
9392            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9393            if (!isDebuggable) {
9394                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9395                    throw new SecurityException("Process not debuggable: " + app.packageName);
9396                }
9397            }
9398
9399            mOpenGlTraceApp = processName;
9400        }
9401    }
9402
9403    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9404            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9405        synchronized (this) {
9406            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9407            if (!isDebuggable) {
9408                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9409                    throw new SecurityException("Process not debuggable: " + app.packageName);
9410                }
9411            }
9412            mProfileApp = processName;
9413            mProfileFile = profileFile;
9414            if (mProfileFd != null) {
9415                try {
9416                    mProfileFd.close();
9417                } catch (IOException e) {
9418                }
9419                mProfileFd = null;
9420            }
9421            mProfileFd = profileFd;
9422            mProfileType = 0;
9423            mAutoStopProfiler = autoStopProfiler;
9424        }
9425    }
9426
9427    @Override
9428    public void setAlwaysFinish(boolean enabled) {
9429        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9430                "setAlwaysFinish()");
9431
9432        Settings.Global.putInt(
9433                mContext.getContentResolver(),
9434                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9435
9436        synchronized (this) {
9437            mAlwaysFinishActivities = enabled;
9438        }
9439    }
9440
9441    @Override
9442    public void setActivityController(IActivityController controller) {
9443        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9444                "setActivityController()");
9445        synchronized (this) {
9446            mController = controller;
9447            Watchdog.getInstance().setActivityController(controller);
9448        }
9449    }
9450
9451    @Override
9452    public void setUserIsMonkey(boolean userIsMonkey) {
9453        synchronized (this) {
9454            synchronized (mPidsSelfLocked) {
9455                final int callingPid = Binder.getCallingPid();
9456                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9457                if (precessRecord == null) {
9458                    throw new SecurityException("Unknown process: " + callingPid);
9459                }
9460                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9461                    throw new SecurityException("Only an instrumentation process "
9462                            + "with a UiAutomation can call setUserIsMonkey");
9463                }
9464            }
9465            mUserIsMonkey = userIsMonkey;
9466        }
9467    }
9468
9469    @Override
9470    public boolean isUserAMonkey() {
9471        synchronized (this) {
9472            // If there is a controller also implies the user is a monkey.
9473            return (mUserIsMonkey || mController != null);
9474        }
9475    }
9476
9477    public void requestBugReport() {
9478        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9479        SystemProperties.set("ctl.start", "bugreport");
9480    }
9481
9482    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9483        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9484    }
9485
9486    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9487        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9488            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9489        }
9490        return KEY_DISPATCHING_TIMEOUT;
9491    }
9492
9493    @Override
9494    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9495        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9496                != PackageManager.PERMISSION_GRANTED) {
9497            throw new SecurityException("Requires permission "
9498                    + android.Manifest.permission.FILTER_EVENTS);
9499        }
9500        ProcessRecord proc;
9501        long timeout;
9502        synchronized (this) {
9503            synchronized (mPidsSelfLocked) {
9504                proc = mPidsSelfLocked.get(pid);
9505            }
9506            timeout = getInputDispatchingTimeoutLocked(proc);
9507        }
9508
9509        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9510            return -1;
9511        }
9512
9513        return timeout;
9514    }
9515
9516    /**
9517     * Handle input dispatching timeouts.
9518     * Returns whether input dispatching should be aborted or not.
9519     */
9520    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9521            final ActivityRecord activity, final ActivityRecord parent,
9522            final boolean aboveSystem, String reason) {
9523        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9524                != PackageManager.PERMISSION_GRANTED) {
9525            throw new SecurityException("Requires permission "
9526                    + android.Manifest.permission.FILTER_EVENTS);
9527        }
9528
9529        final String annotation;
9530        if (reason == null) {
9531            annotation = "Input dispatching timed out";
9532        } else {
9533            annotation = "Input dispatching timed out (" + reason + ")";
9534        }
9535
9536        if (proc != null) {
9537            synchronized (this) {
9538                if (proc.debugging) {
9539                    return false;
9540                }
9541
9542                if (mDidDexOpt) {
9543                    // Give more time since we were dexopting.
9544                    mDidDexOpt = false;
9545                    return false;
9546                }
9547
9548                if (proc.instrumentationClass != null) {
9549                    Bundle info = new Bundle();
9550                    info.putString("shortMsg", "keyDispatchingTimedOut");
9551                    info.putString("longMsg", annotation);
9552                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9553                    return true;
9554                }
9555            }
9556            mHandler.post(new Runnable() {
9557                @Override
9558                public void run() {
9559                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9560                }
9561            });
9562        }
9563
9564        return true;
9565    }
9566
9567    public Bundle getAssistContextExtras(int requestType) {
9568        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9569                "getAssistContextExtras()");
9570        PendingAssistExtras pae;
9571        Bundle extras = new Bundle();
9572        synchronized (this) {
9573            ActivityRecord activity = getFocusedStack().mResumedActivity;
9574            if (activity == null) {
9575                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9576                return null;
9577            }
9578            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9579            if (activity.app == null || activity.app.thread == null) {
9580                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9581                return extras;
9582            }
9583            if (activity.app.pid == Binder.getCallingPid()) {
9584                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9585                return extras;
9586            }
9587            pae = new PendingAssistExtras(activity);
9588            try {
9589                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9590                        requestType);
9591                mPendingAssistExtras.add(pae);
9592                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9593            } catch (RemoteException e) {
9594                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9595                return extras;
9596            }
9597        }
9598        synchronized (pae) {
9599            while (!pae.haveResult) {
9600                try {
9601                    pae.wait();
9602                } catch (InterruptedException e) {
9603                }
9604            }
9605            if (pae.result != null) {
9606                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9607            }
9608        }
9609        synchronized (this) {
9610            mPendingAssistExtras.remove(pae);
9611            mHandler.removeCallbacks(pae);
9612        }
9613        return extras;
9614    }
9615
9616    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9617        PendingAssistExtras pae = (PendingAssistExtras)token;
9618        synchronized (pae) {
9619            pae.result = extras;
9620            pae.haveResult = true;
9621            pae.notifyAll();
9622        }
9623    }
9624
9625    public void registerProcessObserver(IProcessObserver observer) {
9626        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9627                "registerProcessObserver()");
9628        synchronized (this) {
9629            mProcessObservers.register(observer);
9630        }
9631    }
9632
9633    @Override
9634    public void unregisterProcessObserver(IProcessObserver observer) {
9635        synchronized (this) {
9636            mProcessObservers.unregister(observer);
9637        }
9638    }
9639
9640    @Override
9641    public boolean convertFromTranslucent(IBinder token) {
9642        final long origId = Binder.clearCallingIdentity();
9643        try {
9644            synchronized (this) {
9645                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9646                if (r == null) {
9647                    return false;
9648                }
9649                if (r.changeWindowTranslucency(true)) {
9650                    mWindowManager.setAppFullscreen(token, true);
9651                    r.task.stack.releaseMediaResources();
9652                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9653                    return true;
9654                }
9655                return false;
9656            }
9657        } finally {
9658            Binder.restoreCallingIdentity(origId);
9659        }
9660    }
9661
9662    @Override
9663    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9664        final long origId = Binder.clearCallingIdentity();
9665        try {
9666            synchronized (this) {
9667                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9668                if (r == null) {
9669                    return false;
9670                }
9671                int index = r.task.mActivities.lastIndexOf(r);
9672                if (index > 0) {
9673                    ActivityRecord under = r.task.mActivities.get(index - 1);
9674                    under.returningOptions = options;
9675                }
9676                if (r.changeWindowTranslucency(false)) {
9677                    r.task.stack.convertToTranslucent(r);
9678                    mWindowManager.setAppFullscreen(token, false);
9679                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9680                    return true;
9681                } else {
9682                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9683                    return false;
9684                }
9685            }
9686        } finally {
9687            Binder.restoreCallingIdentity(origId);
9688        }
9689    }
9690
9691    @Override
9692    public boolean setMediaPlaying(IBinder token, boolean playing) {
9693        final long origId = Binder.clearCallingIdentity();
9694        try {
9695            synchronized (this) {
9696                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9697                if (r != null) {
9698                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9699                }
9700            }
9701            return false;
9702        } finally {
9703            Binder.restoreCallingIdentity(origId);
9704        }
9705    }
9706
9707    @Override
9708    public boolean isBackgroundMediaPlaying(IBinder token) {
9709        final long origId = Binder.clearCallingIdentity();
9710        try {
9711            synchronized (this) {
9712                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9713                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9714                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9715                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9716                return playing;
9717            }
9718        } finally {
9719            Binder.restoreCallingIdentity(origId);
9720        }
9721    }
9722
9723    @Override
9724    public ActivityOptions getActivityOptions(IBinder token) {
9725        final long origId = Binder.clearCallingIdentity();
9726        try {
9727            synchronized (this) {
9728                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9729                if (r != null) {
9730                    final ActivityOptions activityOptions = r.pendingOptions;
9731                    r.pendingOptions = null;
9732                    return activityOptions;
9733                }
9734                return null;
9735            }
9736        } finally {
9737            Binder.restoreCallingIdentity(origId);
9738        }
9739    }
9740
9741    @Override
9742    public void setImmersive(IBinder token, boolean immersive) {
9743        synchronized(this) {
9744            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9745            if (r == null) {
9746                throw new IllegalArgumentException();
9747            }
9748            r.immersive = immersive;
9749
9750            // update associated state if we're frontmost
9751            if (r == mFocusedActivity) {
9752                if (DEBUG_IMMERSIVE) {
9753                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9754                }
9755                applyUpdateLockStateLocked(r);
9756            }
9757        }
9758    }
9759
9760    @Override
9761    public boolean isImmersive(IBinder token) {
9762        synchronized (this) {
9763            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9764            if (r == null) {
9765                throw new IllegalArgumentException();
9766            }
9767            return r.immersive;
9768        }
9769    }
9770
9771    public boolean isTopActivityImmersive() {
9772        enforceNotIsolatedCaller("startActivity");
9773        synchronized (this) {
9774            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9775            return (r != null) ? r.immersive : false;
9776        }
9777    }
9778
9779    @Override
9780    public boolean isTopOfTask(IBinder token) {
9781        synchronized (this) {
9782            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9783            if (r == null) {
9784                throw new IllegalArgumentException();
9785            }
9786            return r.task.getTopActivity() == r;
9787        }
9788    }
9789
9790    public final void enterSafeMode() {
9791        synchronized(this) {
9792            // It only makes sense to do this before the system is ready
9793            // and started launching other packages.
9794            if (!mSystemReady) {
9795                try {
9796                    AppGlobals.getPackageManager().enterSafeMode();
9797                } catch (RemoteException e) {
9798                }
9799            }
9800
9801            mSafeMode = true;
9802        }
9803    }
9804
9805    public final void showSafeModeOverlay() {
9806        View v = LayoutInflater.from(mContext).inflate(
9807                com.android.internal.R.layout.safe_mode, null);
9808        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9809        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9810        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9811        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9812        lp.gravity = Gravity.BOTTOM | Gravity.START;
9813        lp.format = v.getBackground().getOpacity();
9814        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9815                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9816        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9817        ((WindowManager)mContext.getSystemService(
9818                Context.WINDOW_SERVICE)).addView(v, lp);
9819    }
9820
9821    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9822        if (!(sender instanceof PendingIntentRecord)) {
9823            return;
9824        }
9825        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9826        synchronized (stats) {
9827            if (mBatteryStatsService.isOnBattery()) {
9828                mBatteryStatsService.enforceCallingPermission();
9829                PendingIntentRecord rec = (PendingIntentRecord)sender;
9830                int MY_UID = Binder.getCallingUid();
9831                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9832                BatteryStatsImpl.Uid.Pkg pkg =
9833                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9834                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9835                pkg.incWakeupsLocked();
9836            }
9837        }
9838    }
9839
9840    public boolean killPids(int[] pids, String pReason, boolean secure) {
9841        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9842            throw new SecurityException("killPids only available to the system");
9843        }
9844        String reason = (pReason == null) ? "Unknown" : pReason;
9845        // XXX Note: don't acquire main activity lock here, because the window
9846        // manager calls in with its locks held.
9847
9848        boolean killed = false;
9849        synchronized (mPidsSelfLocked) {
9850            int[] types = new int[pids.length];
9851            int worstType = 0;
9852            for (int i=0; i<pids.length; i++) {
9853                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9854                if (proc != null) {
9855                    int type = proc.setAdj;
9856                    types[i] = type;
9857                    if (type > worstType) {
9858                        worstType = type;
9859                    }
9860                }
9861            }
9862
9863            // If the worst oom_adj is somewhere in the cached proc LRU range,
9864            // then constrain it so we will kill all cached procs.
9865            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9866                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9867                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9868            }
9869
9870            // If this is not a secure call, don't let it kill processes that
9871            // are important.
9872            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9873                worstType = ProcessList.SERVICE_ADJ;
9874            }
9875
9876            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9877            for (int i=0; i<pids.length; i++) {
9878                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9879                if (proc == null) {
9880                    continue;
9881                }
9882                int adj = proc.setAdj;
9883                if (adj >= worstType && !proc.killedByAm) {
9884                    killUnneededProcessLocked(proc, reason);
9885                    killed = true;
9886                }
9887            }
9888        }
9889        return killed;
9890    }
9891
9892    @Override
9893    public void killUid(int uid, String reason) {
9894        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9895            throw new SecurityException("killUid only available to the system");
9896        }
9897        synchronized (this) {
9898            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9899                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9900                    reason != null ? reason : "kill uid");
9901        }
9902    }
9903
9904    @Override
9905    public boolean killProcessesBelowForeground(String reason) {
9906        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9907            throw new SecurityException("killProcessesBelowForeground() only available to system");
9908        }
9909
9910        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9911    }
9912
9913    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9914        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9915            throw new SecurityException("killProcessesBelowAdj() only available to system");
9916        }
9917
9918        boolean killed = false;
9919        synchronized (mPidsSelfLocked) {
9920            final int size = mPidsSelfLocked.size();
9921            for (int i = 0; i < size; i++) {
9922                final int pid = mPidsSelfLocked.keyAt(i);
9923                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9924                if (proc == null) continue;
9925
9926                final int adj = proc.setAdj;
9927                if (adj > belowAdj && !proc.killedByAm) {
9928                    killUnneededProcessLocked(proc, reason);
9929                    killed = true;
9930                }
9931            }
9932        }
9933        return killed;
9934    }
9935
9936    @Override
9937    public void hang(final IBinder who, boolean allowRestart) {
9938        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9939                != PackageManager.PERMISSION_GRANTED) {
9940            throw new SecurityException("Requires permission "
9941                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9942        }
9943
9944        final IBinder.DeathRecipient death = new DeathRecipient() {
9945            @Override
9946            public void binderDied() {
9947                synchronized (this) {
9948                    notifyAll();
9949                }
9950            }
9951        };
9952
9953        try {
9954            who.linkToDeath(death, 0);
9955        } catch (RemoteException e) {
9956            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9957            return;
9958        }
9959
9960        synchronized (this) {
9961            Watchdog.getInstance().setAllowRestart(allowRestart);
9962            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9963            synchronized (death) {
9964                while (who.isBinderAlive()) {
9965                    try {
9966                        death.wait();
9967                    } catch (InterruptedException e) {
9968                    }
9969                }
9970            }
9971            Watchdog.getInstance().setAllowRestart(true);
9972        }
9973    }
9974
9975    @Override
9976    public void restart() {
9977        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9978                != PackageManager.PERMISSION_GRANTED) {
9979            throw new SecurityException("Requires permission "
9980                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9981        }
9982
9983        Log.i(TAG, "Sending shutdown broadcast...");
9984
9985        BroadcastReceiver br = new BroadcastReceiver() {
9986            @Override public void onReceive(Context context, Intent intent) {
9987                // Now the broadcast is done, finish up the low-level shutdown.
9988                Log.i(TAG, "Shutting down activity manager...");
9989                shutdown(10000);
9990                Log.i(TAG, "Shutdown complete, restarting!");
9991                Process.killProcess(Process.myPid());
9992                System.exit(10);
9993            }
9994        };
9995
9996        // First send the high-level shut down broadcast.
9997        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9998        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9999        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10000        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10001        mContext.sendOrderedBroadcastAsUser(intent,
10002                UserHandle.ALL, null, br, mHandler, 0, null, null);
10003        */
10004        br.onReceive(mContext, intent);
10005    }
10006
10007    private long getLowRamTimeSinceIdle(long now) {
10008        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10009    }
10010
10011    @Override
10012    public void performIdleMaintenance() {
10013        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10014                != PackageManager.PERMISSION_GRANTED) {
10015            throw new SecurityException("Requires permission "
10016                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10017        }
10018
10019        synchronized (this) {
10020            final long now = SystemClock.uptimeMillis();
10021            final long timeSinceLastIdle = now - mLastIdleTime;
10022            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10023            mLastIdleTime = now;
10024            mLowRamTimeSinceLastIdle = 0;
10025            if (mLowRamStartTime != 0) {
10026                mLowRamStartTime = now;
10027            }
10028
10029            StringBuilder sb = new StringBuilder(128);
10030            sb.append("Idle maintenance over ");
10031            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10032            sb.append(" low RAM for ");
10033            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10034            Slog.i(TAG, sb.toString());
10035
10036            // If at least 1/3 of our time since the last idle period has been spent
10037            // with RAM low, then we want to kill processes.
10038            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10039
10040            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10041                ProcessRecord proc = mLruProcesses.get(i);
10042                if (proc.notCachedSinceIdle) {
10043                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10044                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10045                        if (doKilling && proc.initialIdlePss != 0
10046                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10047                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10048                                    + " from " + proc.initialIdlePss + ")");
10049                        }
10050                    }
10051                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10052                    proc.notCachedSinceIdle = true;
10053                    proc.initialIdlePss = 0;
10054                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10055                            isSleeping(), now);
10056                }
10057            }
10058
10059            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10060            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10061        }
10062    }
10063
10064    private void retrieveSettings() {
10065        final ContentResolver resolver = mContext.getContentResolver();
10066        String debugApp = Settings.Global.getString(
10067            resolver, Settings.Global.DEBUG_APP);
10068        boolean waitForDebugger = Settings.Global.getInt(
10069            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10070        boolean alwaysFinishActivities = Settings.Global.getInt(
10071            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10072        boolean forceRtl = Settings.Global.getInt(
10073                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10074        // Transfer any global setting for forcing RTL layout, into a System Property
10075        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10076
10077        Configuration configuration = new Configuration();
10078        Settings.System.getConfiguration(resolver, configuration);
10079        if (forceRtl) {
10080            // This will take care of setting the correct layout direction flags
10081            configuration.setLayoutDirection(configuration.locale);
10082        }
10083
10084        synchronized (this) {
10085            mDebugApp = mOrigDebugApp = debugApp;
10086            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10087            mAlwaysFinishActivities = alwaysFinishActivities;
10088            // This happens before any activities are started, so we can
10089            // change mConfiguration in-place.
10090            updateConfigurationLocked(configuration, null, false, true);
10091            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10092        }
10093    }
10094
10095    public boolean testIsSystemReady() {
10096        // no need to synchronize(this) just to read & return the value
10097        return mSystemReady;
10098    }
10099
10100    private static File getCalledPreBootReceiversFile() {
10101        File dataDir = Environment.getDataDirectory();
10102        File systemDir = new File(dataDir, "system");
10103        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10104        return fname;
10105    }
10106
10107    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10108        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10109        File file = getCalledPreBootReceiversFile();
10110        FileInputStream fis = null;
10111        try {
10112            fis = new FileInputStream(file);
10113            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10114            int fvers = dis.readInt();
10115            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10116                String vers = dis.readUTF();
10117                String codename = dis.readUTF();
10118                String build = dis.readUTF();
10119                if (android.os.Build.VERSION.RELEASE.equals(vers)
10120                        && android.os.Build.VERSION.CODENAME.equals(codename)
10121                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10122                    int num = dis.readInt();
10123                    while (num > 0) {
10124                        num--;
10125                        String pkg = dis.readUTF();
10126                        String cls = dis.readUTF();
10127                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10128                    }
10129                }
10130            }
10131        } catch (FileNotFoundException e) {
10132        } catch (IOException e) {
10133            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10134        } finally {
10135            if (fis != null) {
10136                try {
10137                    fis.close();
10138                } catch (IOException e) {
10139                }
10140            }
10141        }
10142        return lastDoneReceivers;
10143    }
10144
10145    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10146        File file = getCalledPreBootReceiversFile();
10147        FileOutputStream fos = null;
10148        DataOutputStream dos = null;
10149        try {
10150            fos = new FileOutputStream(file);
10151            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10152            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10153            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10154            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10155            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10156            dos.writeInt(list.size());
10157            for (int i=0; i<list.size(); i++) {
10158                dos.writeUTF(list.get(i).getPackageName());
10159                dos.writeUTF(list.get(i).getClassName());
10160            }
10161        } catch (IOException e) {
10162            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10163            file.delete();
10164        } finally {
10165            FileUtils.sync(fos);
10166            if (dos != null) {
10167                try {
10168                    dos.close();
10169                } catch (IOException e) {
10170                    // TODO Auto-generated catch block
10171                    e.printStackTrace();
10172                }
10173            }
10174        }
10175    }
10176
10177    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10178            ArrayList<ComponentName> doneReceivers, int userId) {
10179        boolean waitingUpdate = false;
10180        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10181        List<ResolveInfo> ris = null;
10182        try {
10183            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10184                    intent, null, 0, userId);
10185        } catch (RemoteException e) {
10186        }
10187        if (ris != null) {
10188            for (int i=ris.size()-1; i>=0; i--) {
10189                if ((ris.get(i).activityInfo.applicationInfo.flags
10190                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10191                    ris.remove(i);
10192                }
10193            }
10194            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10195
10196            // For User 0, load the version number. When delivering to a new user, deliver
10197            // to all receivers.
10198            if (userId == UserHandle.USER_OWNER) {
10199                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10200                for (int i=0; i<ris.size(); i++) {
10201                    ActivityInfo ai = ris.get(i).activityInfo;
10202                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10203                    if (lastDoneReceivers.contains(comp)) {
10204                        // We already did the pre boot receiver for this app with the current
10205                        // platform version, so don't do it again...
10206                        ris.remove(i);
10207                        i--;
10208                        // ...however, do keep it as one that has been done, so we don't
10209                        // forget about it when rewriting the file of last done receivers.
10210                        doneReceivers.add(comp);
10211                    }
10212                }
10213            }
10214
10215            // If primary user, send broadcast to all available users, else just to userId
10216            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10217                    : new int[] { userId };
10218            for (int i = 0; i < ris.size(); i++) {
10219                ActivityInfo ai = ris.get(i).activityInfo;
10220                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10221                doneReceivers.add(comp);
10222                intent.setComponent(comp);
10223                for (int j=0; j<users.length; j++) {
10224                    IIntentReceiver finisher = null;
10225                    // On last receiver and user, set up a completion callback
10226                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10227                        finisher = new IIntentReceiver.Stub() {
10228                            public void performReceive(Intent intent, int resultCode,
10229                                    String data, Bundle extras, boolean ordered,
10230                                    boolean sticky, int sendingUser) {
10231                                // The raw IIntentReceiver interface is called
10232                                // with the AM lock held, so redispatch to
10233                                // execute our code without the lock.
10234                                mHandler.post(onFinishCallback);
10235                            }
10236                        };
10237                    }
10238                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10239                            + " for user " + users[j]);
10240                    broadcastIntentLocked(null, null, intent, null, finisher,
10241                            0, null, null, null, AppOpsManager.OP_NONE,
10242                            true, false, MY_PID, Process.SYSTEM_UID,
10243                            users[j]);
10244                    if (finisher != null) {
10245                        waitingUpdate = true;
10246                    }
10247                }
10248            }
10249        }
10250
10251        return waitingUpdate;
10252    }
10253
10254    public void systemReady(final Runnable goingCallback) {
10255        synchronized(this) {
10256            if (mSystemReady) {
10257                // If we're done calling all the receivers, run the next "boot phase" passed in
10258                // by the SystemServer
10259                if (goingCallback != null) {
10260                    goingCallback.run();
10261                }
10262                return;
10263            }
10264
10265            // Make sure we have the current profile info, since it is needed for
10266            // security checks.
10267            updateCurrentProfileIdsLocked();
10268
10269            if (mRecentTasks == null) {
10270                mRecentTasks = mTaskPersister.restoreTasksLocked();
10271                if (!mRecentTasks.isEmpty()) {
10272                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10273                }
10274                mTaskPersister.startPersisting();
10275            }
10276
10277            // Check to see if there are any update receivers to run.
10278            if (!mDidUpdate) {
10279                if (mWaitingUpdate) {
10280                    return;
10281                }
10282                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10283                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10284                    public void run() {
10285                        synchronized (ActivityManagerService.this) {
10286                            mDidUpdate = true;
10287                        }
10288                        writeLastDonePreBootReceivers(doneReceivers);
10289                        showBootMessage(mContext.getText(
10290                                R.string.android_upgrading_complete),
10291                                false);
10292                        systemReady(goingCallback);
10293                    }
10294                }, doneReceivers, UserHandle.USER_OWNER);
10295
10296                if (mWaitingUpdate) {
10297                    return;
10298                }
10299                mDidUpdate = true;
10300            }
10301
10302            mAppOpsService.systemReady();
10303            mSystemReady = true;
10304        }
10305
10306        ArrayList<ProcessRecord> procsToKill = null;
10307        synchronized(mPidsSelfLocked) {
10308            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10309                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10310                if (!isAllowedWhileBooting(proc.info)){
10311                    if (procsToKill == null) {
10312                        procsToKill = new ArrayList<ProcessRecord>();
10313                    }
10314                    procsToKill.add(proc);
10315                }
10316            }
10317        }
10318
10319        synchronized(this) {
10320            if (procsToKill != null) {
10321                for (int i=procsToKill.size()-1; i>=0; i--) {
10322                    ProcessRecord proc = procsToKill.get(i);
10323                    Slog.i(TAG, "Removing system update proc: " + proc);
10324                    removeProcessLocked(proc, true, false, "system update done");
10325                }
10326            }
10327
10328            // Now that we have cleaned up any update processes, we
10329            // are ready to start launching real processes and know that
10330            // we won't trample on them any more.
10331            mProcessesReady = true;
10332        }
10333
10334        Slog.i(TAG, "System now ready");
10335        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10336            SystemClock.uptimeMillis());
10337
10338        synchronized(this) {
10339            // Make sure we have no pre-ready processes sitting around.
10340
10341            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10342                ResolveInfo ri = mContext.getPackageManager()
10343                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10344                                STOCK_PM_FLAGS);
10345                CharSequence errorMsg = null;
10346                if (ri != null) {
10347                    ActivityInfo ai = ri.activityInfo;
10348                    ApplicationInfo app = ai.applicationInfo;
10349                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10350                        mTopAction = Intent.ACTION_FACTORY_TEST;
10351                        mTopData = null;
10352                        mTopComponent = new ComponentName(app.packageName,
10353                                ai.name);
10354                    } else {
10355                        errorMsg = mContext.getResources().getText(
10356                                com.android.internal.R.string.factorytest_not_system);
10357                    }
10358                } else {
10359                    errorMsg = mContext.getResources().getText(
10360                            com.android.internal.R.string.factorytest_no_action);
10361                }
10362                if (errorMsg != null) {
10363                    mTopAction = null;
10364                    mTopData = null;
10365                    mTopComponent = null;
10366                    Message msg = Message.obtain();
10367                    msg.what = SHOW_FACTORY_ERROR_MSG;
10368                    msg.getData().putCharSequence("msg", errorMsg);
10369                    mHandler.sendMessage(msg);
10370                }
10371            }
10372        }
10373
10374        retrieveSettings();
10375
10376        synchronized (this) {
10377            readGrantedUriPermissionsLocked();
10378        }
10379
10380        if (goingCallback != null) goingCallback.run();
10381
10382        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10383                Integer.toString(mCurrentUserId), mCurrentUserId);
10384        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10385                Integer.toString(mCurrentUserId), mCurrentUserId);
10386        mSystemServiceManager.startUser(mCurrentUserId);
10387
10388        synchronized (this) {
10389            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10390                try {
10391                    List apps = AppGlobals.getPackageManager().
10392                        getPersistentApplications(STOCK_PM_FLAGS);
10393                    if (apps != null) {
10394                        int N = apps.size();
10395                        int i;
10396                        for (i=0; i<N; i++) {
10397                            ApplicationInfo info
10398                                = (ApplicationInfo)apps.get(i);
10399                            if (info != null &&
10400                                    !info.packageName.equals("android")) {
10401                                addAppLocked(info, false, null /* ABI override */);
10402                            }
10403                        }
10404                    }
10405                } catch (RemoteException ex) {
10406                    // pm is in same process, this will never happen.
10407                }
10408            }
10409
10410            // Start up initial activity.
10411            mBooting = true;
10412
10413            try {
10414                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10415                    Message msg = Message.obtain();
10416                    msg.what = SHOW_UID_ERROR_MSG;
10417                    mHandler.sendMessage(msg);
10418                }
10419            } catch (RemoteException e) {
10420            }
10421
10422            long ident = Binder.clearCallingIdentity();
10423            try {
10424                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10425                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10426                        | Intent.FLAG_RECEIVER_FOREGROUND);
10427                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10428                broadcastIntentLocked(null, null, intent,
10429                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10430                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10431                intent = new Intent(Intent.ACTION_USER_STARTING);
10432                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10433                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10434                broadcastIntentLocked(null, null, intent,
10435                        null, new IIntentReceiver.Stub() {
10436                            @Override
10437                            public void performReceive(Intent intent, int resultCode, String data,
10438                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10439                                    throws RemoteException {
10440                            }
10441                        }, 0, null, null,
10442                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10443                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10444            } catch (Throwable t) {
10445                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10446            } finally {
10447                Binder.restoreCallingIdentity(ident);
10448            }
10449            mStackSupervisor.resumeTopActivitiesLocked();
10450            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10451        }
10452    }
10453
10454    private boolean makeAppCrashingLocked(ProcessRecord app,
10455            String shortMsg, String longMsg, String stackTrace) {
10456        app.crashing = true;
10457        app.crashingReport = generateProcessError(app,
10458                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10459        startAppProblemLocked(app);
10460        app.stopFreezingAllLocked();
10461        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10462    }
10463
10464    private void makeAppNotRespondingLocked(ProcessRecord app,
10465            String activity, String shortMsg, String longMsg) {
10466        app.notResponding = true;
10467        app.notRespondingReport = generateProcessError(app,
10468                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10469                activity, shortMsg, longMsg, null);
10470        startAppProblemLocked(app);
10471        app.stopFreezingAllLocked();
10472    }
10473
10474    /**
10475     * Generate a process error record, suitable for attachment to a ProcessRecord.
10476     *
10477     * @param app The ProcessRecord in which the error occurred.
10478     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10479     *                      ActivityManager.AppErrorStateInfo
10480     * @param activity The activity associated with the crash, if known.
10481     * @param shortMsg Short message describing the crash.
10482     * @param longMsg Long message describing the crash.
10483     * @param stackTrace Full crash stack trace, may be null.
10484     *
10485     * @return Returns a fully-formed AppErrorStateInfo record.
10486     */
10487    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10488            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10489        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10490
10491        report.condition = condition;
10492        report.processName = app.processName;
10493        report.pid = app.pid;
10494        report.uid = app.info.uid;
10495        report.tag = activity;
10496        report.shortMsg = shortMsg;
10497        report.longMsg = longMsg;
10498        report.stackTrace = stackTrace;
10499
10500        return report;
10501    }
10502
10503    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10504        synchronized (this) {
10505            app.crashing = false;
10506            app.crashingReport = null;
10507            app.notResponding = false;
10508            app.notRespondingReport = null;
10509            if (app.anrDialog == fromDialog) {
10510                app.anrDialog = null;
10511            }
10512            if (app.waitDialog == fromDialog) {
10513                app.waitDialog = null;
10514            }
10515            if (app.pid > 0 && app.pid != MY_PID) {
10516                handleAppCrashLocked(app, null, null, null);
10517                killUnneededProcessLocked(app, "user request after error");
10518            }
10519        }
10520    }
10521
10522    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10523            String stackTrace) {
10524        long now = SystemClock.uptimeMillis();
10525
10526        Long crashTime;
10527        if (!app.isolated) {
10528            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10529        } else {
10530            crashTime = null;
10531        }
10532        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10533            // This process loses!
10534            Slog.w(TAG, "Process " + app.info.processName
10535                    + " has crashed too many times: killing!");
10536            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10537                    app.userId, app.info.processName, app.uid);
10538            mStackSupervisor.handleAppCrashLocked(app);
10539            if (!app.persistent) {
10540                // We don't want to start this process again until the user
10541                // explicitly does so...  but for persistent process, we really
10542                // need to keep it running.  If a persistent process is actually
10543                // repeatedly crashing, then badness for everyone.
10544                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10545                        app.info.processName);
10546                if (!app.isolated) {
10547                    // XXX We don't have a way to mark isolated processes
10548                    // as bad, since they don't have a peristent identity.
10549                    mBadProcesses.put(app.info.processName, app.uid,
10550                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10551                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10552                }
10553                app.bad = true;
10554                app.removed = true;
10555                // Don't let services in this process be restarted and potentially
10556                // annoy the user repeatedly.  Unless it is persistent, since those
10557                // processes run critical code.
10558                removeProcessLocked(app, false, false, "crash");
10559                mStackSupervisor.resumeTopActivitiesLocked();
10560                return false;
10561            }
10562            mStackSupervisor.resumeTopActivitiesLocked();
10563        } else {
10564            mStackSupervisor.finishTopRunningActivityLocked(app);
10565        }
10566
10567        // Bump up the crash count of any services currently running in the proc.
10568        for (int i=app.services.size()-1; i>=0; i--) {
10569            // Any services running in the application need to be placed
10570            // back in the pending list.
10571            ServiceRecord sr = app.services.valueAt(i);
10572            sr.crashCount++;
10573        }
10574
10575        // If the crashing process is what we consider to be the "home process" and it has been
10576        // replaced by a third-party app, clear the package preferred activities from packages
10577        // with a home activity running in the process to prevent a repeatedly crashing app
10578        // from blocking the user to manually clear the list.
10579        final ArrayList<ActivityRecord> activities = app.activities;
10580        if (app == mHomeProcess && activities.size() > 0
10581                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10582            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10583                final ActivityRecord r = activities.get(activityNdx);
10584                if (r.isHomeActivity()) {
10585                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10586                    try {
10587                        ActivityThread.getPackageManager()
10588                                .clearPackagePreferredActivities(r.packageName);
10589                    } catch (RemoteException c) {
10590                        // pm is in same process, this will never happen.
10591                    }
10592                }
10593            }
10594        }
10595
10596        if (!app.isolated) {
10597            // XXX Can't keep track of crash times for isolated processes,
10598            // because they don't have a perisistent identity.
10599            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10600        }
10601
10602        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10603        return true;
10604    }
10605
10606    void startAppProblemLocked(ProcessRecord app) {
10607        if (app.userId == mCurrentUserId) {
10608            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10609                    mContext, app.info.packageName, app.info.flags);
10610        } else {
10611            // If this app is not running under the current user, then we
10612            // can't give it a report button because that would require
10613            // launching the report UI under a different user.
10614            app.errorReportReceiver = null;
10615        }
10616        skipCurrentReceiverLocked(app);
10617    }
10618
10619    void skipCurrentReceiverLocked(ProcessRecord app) {
10620        for (BroadcastQueue queue : mBroadcastQueues) {
10621            queue.skipCurrentReceiverLocked(app);
10622        }
10623    }
10624
10625    /**
10626     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10627     * The application process will exit immediately after this call returns.
10628     * @param app object of the crashing app, null for the system server
10629     * @param crashInfo describing the exception
10630     */
10631    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10632        ProcessRecord r = findAppProcess(app, "Crash");
10633        final String processName = app == null ? "system_server"
10634                : (r == null ? "unknown" : r.processName);
10635
10636        handleApplicationCrashInner("crash", r, processName, crashInfo);
10637    }
10638
10639    /* Native crash reporting uses this inner version because it needs to be somewhat
10640     * decoupled from the AM-managed cleanup lifecycle
10641     */
10642    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10643            ApplicationErrorReport.CrashInfo crashInfo) {
10644        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10645                UserHandle.getUserId(Binder.getCallingUid()), processName,
10646                r == null ? -1 : r.info.flags,
10647                crashInfo.exceptionClassName,
10648                crashInfo.exceptionMessage,
10649                crashInfo.throwFileName,
10650                crashInfo.throwLineNumber);
10651
10652        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10653
10654        crashApplication(r, crashInfo);
10655    }
10656
10657    public void handleApplicationStrictModeViolation(
10658            IBinder app,
10659            int violationMask,
10660            StrictMode.ViolationInfo info) {
10661        ProcessRecord r = findAppProcess(app, "StrictMode");
10662        if (r == null) {
10663            return;
10664        }
10665
10666        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10667            Integer stackFingerprint = info.hashCode();
10668            boolean logIt = true;
10669            synchronized (mAlreadyLoggedViolatedStacks) {
10670                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10671                    logIt = false;
10672                    // TODO: sub-sample into EventLog for these, with
10673                    // the info.durationMillis?  Then we'd get
10674                    // the relative pain numbers, without logging all
10675                    // the stack traces repeatedly.  We'd want to do
10676                    // likewise in the client code, which also does
10677                    // dup suppression, before the Binder call.
10678                } else {
10679                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10680                        mAlreadyLoggedViolatedStacks.clear();
10681                    }
10682                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10683                }
10684            }
10685            if (logIt) {
10686                logStrictModeViolationToDropBox(r, info);
10687            }
10688        }
10689
10690        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10691            AppErrorResult result = new AppErrorResult();
10692            synchronized (this) {
10693                final long origId = Binder.clearCallingIdentity();
10694
10695                Message msg = Message.obtain();
10696                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10697                HashMap<String, Object> data = new HashMap<String, Object>();
10698                data.put("result", result);
10699                data.put("app", r);
10700                data.put("violationMask", violationMask);
10701                data.put("info", info);
10702                msg.obj = data;
10703                mHandler.sendMessage(msg);
10704
10705                Binder.restoreCallingIdentity(origId);
10706            }
10707            int res = result.get();
10708            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10709        }
10710    }
10711
10712    // Depending on the policy in effect, there could be a bunch of
10713    // these in quick succession so we try to batch these together to
10714    // minimize disk writes, number of dropbox entries, and maximize
10715    // compression, by having more fewer, larger records.
10716    private void logStrictModeViolationToDropBox(
10717            ProcessRecord process,
10718            StrictMode.ViolationInfo info) {
10719        if (info == null) {
10720            return;
10721        }
10722        final boolean isSystemApp = process == null ||
10723                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10724                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10725        final String processName = process == null ? "unknown" : process.processName;
10726        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10727        final DropBoxManager dbox = (DropBoxManager)
10728                mContext.getSystemService(Context.DROPBOX_SERVICE);
10729
10730        // Exit early if the dropbox isn't configured to accept this report type.
10731        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10732
10733        boolean bufferWasEmpty;
10734        boolean needsFlush;
10735        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10736        synchronized (sb) {
10737            bufferWasEmpty = sb.length() == 0;
10738            appendDropBoxProcessHeaders(process, processName, sb);
10739            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10740            sb.append("System-App: ").append(isSystemApp).append("\n");
10741            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10742            if (info.violationNumThisLoop != 0) {
10743                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10744            }
10745            if (info.numAnimationsRunning != 0) {
10746                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10747            }
10748            if (info.broadcastIntentAction != null) {
10749                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10750            }
10751            if (info.durationMillis != -1) {
10752                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10753            }
10754            if (info.numInstances != -1) {
10755                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10756            }
10757            if (info.tags != null) {
10758                for (String tag : info.tags) {
10759                    sb.append("Span-Tag: ").append(tag).append("\n");
10760                }
10761            }
10762            sb.append("\n");
10763            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10764                sb.append(info.crashInfo.stackTrace);
10765            }
10766            sb.append("\n");
10767
10768            // Only buffer up to ~64k.  Various logging bits truncate
10769            // things at 128k.
10770            needsFlush = (sb.length() > 64 * 1024);
10771        }
10772
10773        // Flush immediately if the buffer's grown too large, or this
10774        // is a non-system app.  Non-system apps are isolated with a
10775        // different tag & policy and not batched.
10776        //
10777        // Batching is useful during internal testing with
10778        // StrictMode settings turned up high.  Without batching,
10779        // thousands of separate files could be created on boot.
10780        if (!isSystemApp || needsFlush) {
10781            new Thread("Error dump: " + dropboxTag) {
10782                @Override
10783                public void run() {
10784                    String report;
10785                    synchronized (sb) {
10786                        report = sb.toString();
10787                        sb.delete(0, sb.length());
10788                        sb.trimToSize();
10789                    }
10790                    if (report.length() != 0) {
10791                        dbox.addText(dropboxTag, report);
10792                    }
10793                }
10794            }.start();
10795            return;
10796        }
10797
10798        // System app batching:
10799        if (!bufferWasEmpty) {
10800            // An existing dropbox-writing thread is outstanding, so
10801            // we don't need to start it up.  The existing thread will
10802            // catch the buffer appends we just did.
10803            return;
10804        }
10805
10806        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10807        // (After this point, we shouldn't access AMS internal data structures.)
10808        new Thread("Error dump: " + dropboxTag) {
10809            @Override
10810            public void run() {
10811                // 5 second sleep to let stacks arrive and be batched together
10812                try {
10813                    Thread.sleep(5000);  // 5 seconds
10814                } catch (InterruptedException e) {}
10815
10816                String errorReport;
10817                synchronized (mStrictModeBuffer) {
10818                    errorReport = mStrictModeBuffer.toString();
10819                    if (errorReport.length() == 0) {
10820                        return;
10821                    }
10822                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10823                    mStrictModeBuffer.trimToSize();
10824                }
10825                dbox.addText(dropboxTag, errorReport);
10826            }
10827        }.start();
10828    }
10829
10830    /**
10831     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10832     * @param app object of the crashing app, null for the system server
10833     * @param tag reported by the caller
10834     * @param crashInfo describing the context of the error
10835     * @return true if the process should exit immediately (WTF is fatal)
10836     */
10837    public boolean handleApplicationWtf(IBinder app, String tag,
10838            ApplicationErrorReport.CrashInfo crashInfo) {
10839        ProcessRecord r = findAppProcess(app, "WTF");
10840        final String processName = app == null ? "system_server"
10841                : (r == null ? "unknown" : r.processName);
10842
10843        EventLog.writeEvent(EventLogTags.AM_WTF,
10844                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10845                processName,
10846                r == null ? -1 : r.info.flags,
10847                tag, crashInfo.exceptionMessage);
10848
10849        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10850
10851        if (r != null && r.pid != Process.myPid() &&
10852                Settings.Global.getInt(mContext.getContentResolver(),
10853                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10854            crashApplication(r, crashInfo);
10855            return true;
10856        } else {
10857            return false;
10858        }
10859    }
10860
10861    /**
10862     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10863     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10864     */
10865    private ProcessRecord findAppProcess(IBinder app, String reason) {
10866        if (app == null) {
10867            return null;
10868        }
10869
10870        synchronized (this) {
10871            final int NP = mProcessNames.getMap().size();
10872            for (int ip=0; ip<NP; ip++) {
10873                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10874                final int NA = apps.size();
10875                for (int ia=0; ia<NA; ia++) {
10876                    ProcessRecord p = apps.valueAt(ia);
10877                    if (p.thread != null && p.thread.asBinder() == app) {
10878                        return p;
10879                    }
10880                }
10881            }
10882
10883            Slog.w(TAG, "Can't find mystery application for " + reason
10884                    + " from pid=" + Binder.getCallingPid()
10885                    + " uid=" + Binder.getCallingUid() + ": " + app);
10886            return null;
10887        }
10888    }
10889
10890    /**
10891     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10892     * to append various headers to the dropbox log text.
10893     */
10894    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10895            StringBuilder sb) {
10896        // Watchdog thread ends up invoking this function (with
10897        // a null ProcessRecord) to add the stack file to dropbox.
10898        // Do not acquire a lock on this (am) in such cases, as it
10899        // could cause a potential deadlock, if and when watchdog
10900        // is invoked due to unavailability of lock on am and it
10901        // would prevent watchdog from killing system_server.
10902        if (process == null) {
10903            sb.append("Process: ").append(processName).append("\n");
10904            return;
10905        }
10906        // Note: ProcessRecord 'process' is guarded by the service
10907        // instance.  (notably process.pkgList, which could otherwise change
10908        // concurrently during execution of this method)
10909        synchronized (this) {
10910            sb.append("Process: ").append(processName).append("\n");
10911            int flags = process.info.flags;
10912            IPackageManager pm = AppGlobals.getPackageManager();
10913            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10914            for (int ip=0; ip<process.pkgList.size(); ip++) {
10915                String pkg = process.pkgList.keyAt(ip);
10916                sb.append("Package: ").append(pkg);
10917                try {
10918                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10919                    if (pi != null) {
10920                        sb.append(" v").append(pi.versionCode);
10921                        if (pi.versionName != null) {
10922                            sb.append(" (").append(pi.versionName).append(")");
10923                        }
10924                    }
10925                } catch (RemoteException e) {
10926                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10927                }
10928                sb.append("\n");
10929            }
10930        }
10931    }
10932
10933    private static String processClass(ProcessRecord process) {
10934        if (process == null || process.pid == MY_PID) {
10935            return "system_server";
10936        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10937            return "system_app";
10938        } else {
10939            return "data_app";
10940        }
10941    }
10942
10943    /**
10944     * Write a description of an error (crash, WTF, ANR) to the drop box.
10945     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10946     * @param process which caused the error, null means the system server
10947     * @param activity which triggered the error, null if unknown
10948     * @param parent activity related to the error, null if unknown
10949     * @param subject line related to the error, null if absent
10950     * @param report in long form describing the error, null if absent
10951     * @param logFile to include in the report, null if none
10952     * @param crashInfo giving an application stack trace, null if absent
10953     */
10954    public void addErrorToDropBox(String eventType,
10955            ProcessRecord process, String processName, ActivityRecord activity,
10956            ActivityRecord parent, String subject,
10957            final String report, final File logFile,
10958            final ApplicationErrorReport.CrashInfo crashInfo) {
10959        // NOTE -- this must never acquire the ActivityManagerService lock,
10960        // otherwise the watchdog may be prevented from resetting the system.
10961
10962        final String dropboxTag = processClass(process) + "_" + eventType;
10963        final DropBoxManager dbox = (DropBoxManager)
10964                mContext.getSystemService(Context.DROPBOX_SERVICE);
10965
10966        // Exit early if the dropbox isn't configured to accept this report type.
10967        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10968
10969        final StringBuilder sb = new StringBuilder(1024);
10970        appendDropBoxProcessHeaders(process, processName, sb);
10971        if (activity != null) {
10972            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10973        }
10974        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10975            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10976        }
10977        if (parent != null && parent != activity) {
10978            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10979        }
10980        if (subject != null) {
10981            sb.append("Subject: ").append(subject).append("\n");
10982        }
10983        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10984        if (Debug.isDebuggerConnected()) {
10985            sb.append("Debugger: Connected\n");
10986        }
10987        sb.append("\n");
10988
10989        // Do the rest in a worker thread to avoid blocking the caller on I/O
10990        // (After this point, we shouldn't access AMS internal data structures.)
10991        Thread worker = new Thread("Error dump: " + dropboxTag) {
10992            @Override
10993            public void run() {
10994                if (report != null) {
10995                    sb.append(report);
10996                }
10997                if (logFile != null) {
10998                    try {
10999                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11000                                    "\n\n[[TRUNCATED]]"));
11001                    } catch (IOException e) {
11002                        Slog.e(TAG, "Error reading " + logFile, e);
11003                    }
11004                }
11005                if (crashInfo != null && crashInfo.stackTrace != null) {
11006                    sb.append(crashInfo.stackTrace);
11007                }
11008
11009                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11010                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11011                if (lines > 0) {
11012                    sb.append("\n");
11013
11014                    // Merge several logcat streams, and take the last N lines
11015                    InputStreamReader input = null;
11016                    try {
11017                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11018                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11019                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11020
11021                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11022                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11023                        input = new InputStreamReader(logcat.getInputStream());
11024
11025                        int num;
11026                        char[] buf = new char[8192];
11027                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11028                    } catch (IOException e) {
11029                        Slog.e(TAG, "Error running logcat", e);
11030                    } finally {
11031                        if (input != null) try { input.close(); } catch (IOException e) {}
11032                    }
11033                }
11034
11035                dbox.addText(dropboxTag, sb.toString());
11036            }
11037        };
11038
11039        if (process == null) {
11040            // If process is null, we are being called from some internal code
11041            // and may be about to die -- run this synchronously.
11042            worker.run();
11043        } else {
11044            worker.start();
11045        }
11046    }
11047
11048    /**
11049     * Bring up the "unexpected error" dialog box for a crashing app.
11050     * Deal with edge cases (intercepts from instrumented applications,
11051     * ActivityController, error intent receivers, that sort of thing).
11052     * @param r the application crashing
11053     * @param crashInfo describing the failure
11054     */
11055    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11056        long timeMillis = System.currentTimeMillis();
11057        String shortMsg = crashInfo.exceptionClassName;
11058        String longMsg = crashInfo.exceptionMessage;
11059        String stackTrace = crashInfo.stackTrace;
11060        if (shortMsg != null && longMsg != null) {
11061            longMsg = shortMsg + ": " + longMsg;
11062        } else if (shortMsg != null) {
11063            longMsg = shortMsg;
11064        }
11065
11066        AppErrorResult result = new AppErrorResult();
11067        synchronized (this) {
11068            if (mController != null) {
11069                try {
11070                    String name = r != null ? r.processName : null;
11071                    int pid = r != null ? r.pid : Binder.getCallingPid();
11072                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11073                    if (!mController.appCrashed(name, pid,
11074                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11075                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11076                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11077                            Slog.w(TAG, "Skip killing native crashed app " + name
11078                                    + "(" + pid + ") during testing");
11079                        } else {
11080                            Slog.w(TAG, "Force-killing crashed app " + name
11081                                    + " at watcher's request");
11082                            Process.killProcess(pid);
11083                            if (r != null) {
11084                                Process.killProcessGroup(uid, pid);
11085                            }
11086                        }
11087                        return;
11088                    }
11089                } catch (RemoteException e) {
11090                    mController = null;
11091                    Watchdog.getInstance().setActivityController(null);
11092                }
11093            }
11094
11095            final long origId = Binder.clearCallingIdentity();
11096
11097            // If this process is running instrumentation, finish it.
11098            if (r != null && r.instrumentationClass != null) {
11099                Slog.w(TAG, "Error in app " + r.processName
11100                      + " running instrumentation " + r.instrumentationClass + ":");
11101                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11102                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11103                Bundle info = new Bundle();
11104                info.putString("shortMsg", shortMsg);
11105                info.putString("longMsg", longMsg);
11106                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11107                Binder.restoreCallingIdentity(origId);
11108                return;
11109            }
11110
11111            // If we can't identify the process or it's already exceeded its crash quota,
11112            // quit right away without showing a crash dialog.
11113            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11114                Binder.restoreCallingIdentity(origId);
11115                return;
11116            }
11117
11118            Message msg = Message.obtain();
11119            msg.what = SHOW_ERROR_MSG;
11120            HashMap data = new HashMap();
11121            data.put("result", result);
11122            data.put("app", r);
11123            msg.obj = data;
11124            mHandler.sendMessage(msg);
11125
11126            Binder.restoreCallingIdentity(origId);
11127        }
11128
11129        int res = result.get();
11130
11131        Intent appErrorIntent = null;
11132        synchronized (this) {
11133            if (r != null && !r.isolated) {
11134                // XXX Can't keep track of crash time for isolated processes,
11135                // since they don't have a persistent identity.
11136                mProcessCrashTimes.put(r.info.processName, r.uid,
11137                        SystemClock.uptimeMillis());
11138            }
11139            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11140                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11141            }
11142        }
11143
11144        if (appErrorIntent != null) {
11145            try {
11146                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11147            } catch (ActivityNotFoundException e) {
11148                Slog.w(TAG, "bug report receiver dissappeared", e);
11149            }
11150        }
11151    }
11152
11153    Intent createAppErrorIntentLocked(ProcessRecord r,
11154            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11155        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11156        if (report == null) {
11157            return null;
11158        }
11159        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11160        result.setComponent(r.errorReportReceiver);
11161        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11162        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11163        return result;
11164    }
11165
11166    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11167            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11168        if (r.errorReportReceiver == null) {
11169            return null;
11170        }
11171
11172        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11173            return null;
11174        }
11175
11176        ApplicationErrorReport report = new ApplicationErrorReport();
11177        report.packageName = r.info.packageName;
11178        report.installerPackageName = r.errorReportReceiver.getPackageName();
11179        report.processName = r.processName;
11180        report.time = timeMillis;
11181        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11182
11183        if (r.crashing || r.forceCrashReport) {
11184            report.type = ApplicationErrorReport.TYPE_CRASH;
11185            report.crashInfo = crashInfo;
11186        } else if (r.notResponding) {
11187            report.type = ApplicationErrorReport.TYPE_ANR;
11188            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11189
11190            report.anrInfo.activity = r.notRespondingReport.tag;
11191            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11192            report.anrInfo.info = r.notRespondingReport.longMsg;
11193        }
11194
11195        return report;
11196    }
11197
11198    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11199        enforceNotIsolatedCaller("getProcessesInErrorState");
11200        // assume our apps are happy - lazy create the list
11201        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11202
11203        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11204                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11205        int userId = UserHandle.getUserId(Binder.getCallingUid());
11206
11207        synchronized (this) {
11208
11209            // iterate across all processes
11210            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11211                ProcessRecord app = mLruProcesses.get(i);
11212                if (!allUsers && app.userId != userId) {
11213                    continue;
11214                }
11215                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11216                    // This one's in trouble, so we'll generate a report for it
11217                    // crashes are higher priority (in case there's a crash *and* an anr)
11218                    ActivityManager.ProcessErrorStateInfo report = null;
11219                    if (app.crashing) {
11220                        report = app.crashingReport;
11221                    } else if (app.notResponding) {
11222                        report = app.notRespondingReport;
11223                    }
11224
11225                    if (report != null) {
11226                        if (errList == null) {
11227                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11228                        }
11229                        errList.add(report);
11230                    } else {
11231                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11232                                " crashing = " + app.crashing +
11233                                " notResponding = " + app.notResponding);
11234                    }
11235                }
11236            }
11237        }
11238
11239        return errList;
11240    }
11241
11242    static int procStateToImportance(int procState, int memAdj,
11243            ActivityManager.RunningAppProcessInfo currApp) {
11244        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11245        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11246            currApp.lru = memAdj;
11247        } else {
11248            currApp.lru = 0;
11249        }
11250        return imp;
11251    }
11252
11253    private void fillInProcMemInfo(ProcessRecord app,
11254            ActivityManager.RunningAppProcessInfo outInfo) {
11255        outInfo.pid = app.pid;
11256        outInfo.uid = app.info.uid;
11257        if (mHeavyWeightProcess == app) {
11258            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11259        }
11260        if (app.persistent) {
11261            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11262        }
11263        if (app.activities.size() > 0) {
11264            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11265        }
11266        outInfo.lastTrimLevel = app.trimMemoryLevel;
11267        int adj = app.curAdj;
11268        int procState = app.curProcState;
11269        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11270        outInfo.importanceReasonCode = app.adjTypeCode;
11271        outInfo.processState = app.curProcState;
11272    }
11273
11274    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11275        enforceNotIsolatedCaller("getRunningAppProcesses");
11276        // Lazy instantiation of list
11277        List<ActivityManager.RunningAppProcessInfo> runList = null;
11278        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11279                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11280        int userId = UserHandle.getUserId(Binder.getCallingUid());
11281        synchronized (this) {
11282            // Iterate across all processes
11283            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11284                ProcessRecord app = mLruProcesses.get(i);
11285                if (!allUsers && app.userId != userId) {
11286                    continue;
11287                }
11288                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11289                    // Generate process state info for running application
11290                    ActivityManager.RunningAppProcessInfo currApp =
11291                        new ActivityManager.RunningAppProcessInfo(app.processName,
11292                                app.pid, app.getPackageList());
11293                    fillInProcMemInfo(app, currApp);
11294                    if (app.adjSource instanceof ProcessRecord) {
11295                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11296                        currApp.importanceReasonImportance =
11297                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11298                                        app.adjSourceProcState);
11299                    } else if (app.adjSource instanceof ActivityRecord) {
11300                        ActivityRecord r = (ActivityRecord)app.adjSource;
11301                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11302                    }
11303                    if (app.adjTarget instanceof ComponentName) {
11304                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11305                    }
11306                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11307                    //        + " lru=" + currApp.lru);
11308                    if (runList == null) {
11309                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11310                    }
11311                    runList.add(currApp);
11312                }
11313            }
11314        }
11315        return runList;
11316    }
11317
11318    public List<ApplicationInfo> getRunningExternalApplications() {
11319        enforceNotIsolatedCaller("getRunningExternalApplications");
11320        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11321        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11322        if (runningApps != null && runningApps.size() > 0) {
11323            Set<String> extList = new HashSet<String>();
11324            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11325                if (app.pkgList != null) {
11326                    for (String pkg : app.pkgList) {
11327                        extList.add(pkg);
11328                    }
11329                }
11330            }
11331            IPackageManager pm = AppGlobals.getPackageManager();
11332            for (String pkg : extList) {
11333                try {
11334                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11335                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11336                        retList.add(info);
11337                    }
11338                } catch (RemoteException e) {
11339                }
11340            }
11341        }
11342        return retList;
11343    }
11344
11345    @Override
11346    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11347        enforceNotIsolatedCaller("getMyMemoryState");
11348        synchronized (this) {
11349            ProcessRecord proc;
11350            synchronized (mPidsSelfLocked) {
11351                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11352            }
11353            fillInProcMemInfo(proc, outInfo);
11354        }
11355    }
11356
11357    @Override
11358    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11359        if (checkCallingPermission(android.Manifest.permission.DUMP)
11360                != PackageManager.PERMISSION_GRANTED) {
11361            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11362                    + Binder.getCallingPid()
11363                    + ", uid=" + Binder.getCallingUid()
11364                    + " without permission "
11365                    + android.Manifest.permission.DUMP);
11366            return;
11367        }
11368
11369        boolean dumpAll = false;
11370        boolean dumpClient = false;
11371        String dumpPackage = null;
11372
11373        int opti = 0;
11374        while (opti < args.length) {
11375            String opt = args[opti];
11376            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11377                break;
11378            }
11379            opti++;
11380            if ("-a".equals(opt)) {
11381                dumpAll = true;
11382            } else if ("-c".equals(opt)) {
11383                dumpClient = true;
11384            } else if ("-h".equals(opt)) {
11385                pw.println("Activity manager dump options:");
11386                pw.println("  [-a] [-c] [-h] [cmd] ...");
11387                pw.println("  cmd may be one of:");
11388                pw.println("    a[ctivities]: activity stack state");
11389                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11390                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11391                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11392                pw.println("    o[om]: out of memory management");
11393                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11394                pw.println("    provider [COMP_SPEC]: provider client-side state");
11395                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11396                pw.println("    service [COMP_SPEC]: service client-side state");
11397                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11398                pw.println("    all: dump all activities");
11399                pw.println("    top: dump the top activity");
11400                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11401                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11402                pw.println("    a partial substring in a component name, a");
11403                pw.println("    hex object identifier.");
11404                pw.println("  -a: include all available server state.");
11405                pw.println("  -c: include client state.");
11406                return;
11407            } else {
11408                pw.println("Unknown argument: " + opt + "; use -h for help");
11409            }
11410        }
11411
11412        long origId = Binder.clearCallingIdentity();
11413        boolean more = false;
11414        // Is the caller requesting to dump a particular piece of data?
11415        if (opti < args.length) {
11416            String cmd = args[opti];
11417            opti++;
11418            if ("activities".equals(cmd) || "a".equals(cmd)) {
11419                synchronized (this) {
11420                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11421                }
11422            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11423                String[] newArgs;
11424                String name;
11425                if (opti >= args.length) {
11426                    name = null;
11427                    newArgs = EMPTY_STRING_ARRAY;
11428                } else {
11429                    name = args[opti];
11430                    opti++;
11431                    newArgs = new String[args.length - opti];
11432                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11433                            args.length - opti);
11434                }
11435                synchronized (this) {
11436                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11437                }
11438            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11439                String[] newArgs;
11440                String name;
11441                if (opti >= args.length) {
11442                    name = null;
11443                    newArgs = EMPTY_STRING_ARRAY;
11444                } else {
11445                    name = args[opti];
11446                    opti++;
11447                    newArgs = new String[args.length - opti];
11448                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11449                            args.length - opti);
11450                }
11451                synchronized (this) {
11452                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11453                }
11454            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11455                String[] newArgs;
11456                String name;
11457                if (opti >= args.length) {
11458                    name = null;
11459                    newArgs = EMPTY_STRING_ARRAY;
11460                } else {
11461                    name = args[opti];
11462                    opti++;
11463                    newArgs = new String[args.length - opti];
11464                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11465                            args.length - opti);
11466                }
11467                synchronized (this) {
11468                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11469                }
11470            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11471                synchronized (this) {
11472                    dumpOomLocked(fd, pw, args, opti, true);
11473                }
11474            } else if ("provider".equals(cmd)) {
11475                String[] newArgs;
11476                String name;
11477                if (opti >= args.length) {
11478                    name = null;
11479                    newArgs = EMPTY_STRING_ARRAY;
11480                } else {
11481                    name = args[opti];
11482                    opti++;
11483                    newArgs = new String[args.length - opti];
11484                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11485                }
11486                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11487                    pw.println("No providers match: " + name);
11488                    pw.println("Use -h for help.");
11489                }
11490            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11491                synchronized (this) {
11492                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11493                }
11494            } else if ("service".equals(cmd)) {
11495                String[] newArgs;
11496                String name;
11497                if (opti >= args.length) {
11498                    name = null;
11499                    newArgs = EMPTY_STRING_ARRAY;
11500                } else {
11501                    name = args[opti];
11502                    opti++;
11503                    newArgs = new String[args.length - opti];
11504                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11505                            args.length - opti);
11506                }
11507                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11508                    pw.println("No services match: " + name);
11509                    pw.println("Use -h for help.");
11510                }
11511            } else if ("package".equals(cmd)) {
11512                String[] newArgs;
11513                if (opti >= args.length) {
11514                    pw.println("package: no package name specified");
11515                    pw.println("Use -h for help.");
11516                } else {
11517                    dumpPackage = args[opti];
11518                    opti++;
11519                    newArgs = new String[args.length - opti];
11520                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11521                            args.length - opti);
11522                    args = newArgs;
11523                    opti = 0;
11524                    more = true;
11525                }
11526            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11527                synchronized (this) {
11528                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11529                }
11530            } else {
11531                // Dumping a single activity?
11532                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11533                    pw.println("Bad activity command, or no activities match: " + cmd);
11534                    pw.println("Use -h for help.");
11535                }
11536            }
11537            if (!more) {
11538                Binder.restoreCallingIdentity(origId);
11539                return;
11540            }
11541        }
11542
11543        // No piece of data specified, dump everything.
11544        synchronized (this) {
11545            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11546            pw.println();
11547            if (dumpAll) {
11548                pw.println("-------------------------------------------------------------------------------");
11549            }
11550            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11551            pw.println();
11552            if (dumpAll) {
11553                pw.println("-------------------------------------------------------------------------------");
11554            }
11555            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11556            pw.println();
11557            if (dumpAll) {
11558                pw.println("-------------------------------------------------------------------------------");
11559            }
11560            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11561            pw.println();
11562            if (dumpAll) {
11563                pw.println("-------------------------------------------------------------------------------");
11564            }
11565            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11566            pw.println();
11567            if (dumpAll) {
11568                pw.println("-------------------------------------------------------------------------------");
11569            }
11570            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11571        }
11572        Binder.restoreCallingIdentity(origId);
11573    }
11574
11575    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11576            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11577        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11578
11579        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11580                dumpPackage);
11581        boolean needSep = printedAnything;
11582
11583        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11584                dumpPackage, needSep, "  mFocusedActivity: ");
11585        if (printed) {
11586            printedAnything = true;
11587            needSep = false;
11588        }
11589
11590        if (dumpPackage == null) {
11591            if (needSep) {
11592                pw.println();
11593            }
11594            needSep = true;
11595            printedAnything = true;
11596            mStackSupervisor.dump(pw, "  ");
11597        }
11598
11599        if (mRecentTasks.size() > 0) {
11600            boolean printedHeader = false;
11601
11602            final int N = mRecentTasks.size();
11603            for (int i=0; i<N; i++) {
11604                TaskRecord tr = mRecentTasks.get(i);
11605                if (dumpPackage != null) {
11606                    if (tr.realActivity == null ||
11607                            !dumpPackage.equals(tr.realActivity)) {
11608                        continue;
11609                    }
11610                }
11611                if (!printedHeader) {
11612                    if (needSep) {
11613                        pw.println();
11614                    }
11615                    pw.println("  Recent tasks:");
11616                    printedHeader = true;
11617                    printedAnything = true;
11618                }
11619                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11620                        pw.println(tr);
11621                if (dumpAll) {
11622                    mRecentTasks.get(i).dump(pw, "    ");
11623                }
11624            }
11625        }
11626
11627        if (!printedAnything) {
11628            pw.println("  (nothing)");
11629        }
11630    }
11631
11632    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11633            int opti, boolean dumpAll, String dumpPackage) {
11634        boolean needSep = false;
11635        boolean printedAnything = false;
11636        int numPers = 0;
11637
11638        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11639
11640        if (dumpAll) {
11641            final int NP = mProcessNames.getMap().size();
11642            for (int ip=0; ip<NP; ip++) {
11643                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11644                final int NA = procs.size();
11645                for (int ia=0; ia<NA; ia++) {
11646                    ProcessRecord r = procs.valueAt(ia);
11647                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11648                        continue;
11649                    }
11650                    if (!needSep) {
11651                        pw.println("  All known processes:");
11652                        needSep = true;
11653                        printedAnything = true;
11654                    }
11655                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11656                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11657                        pw.print(" "); pw.println(r);
11658                    r.dump(pw, "    ");
11659                    if (r.persistent) {
11660                        numPers++;
11661                    }
11662                }
11663            }
11664        }
11665
11666        if (mIsolatedProcesses.size() > 0) {
11667            boolean printed = false;
11668            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11669                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11670                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11671                    continue;
11672                }
11673                if (!printed) {
11674                    if (needSep) {
11675                        pw.println();
11676                    }
11677                    pw.println("  Isolated process list (sorted by uid):");
11678                    printedAnything = true;
11679                    printed = true;
11680                    needSep = true;
11681                }
11682                pw.println(String.format("%sIsolated #%2d: %s",
11683                        "    ", i, r.toString()));
11684            }
11685        }
11686
11687        if (mLruProcesses.size() > 0) {
11688            if (needSep) {
11689                pw.println();
11690            }
11691            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11692                    pw.print(" total, non-act at ");
11693                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11694                    pw.print(", non-svc at ");
11695                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11696                    pw.println("):");
11697            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11698            needSep = true;
11699            printedAnything = true;
11700        }
11701
11702        if (dumpAll || dumpPackage != null) {
11703            synchronized (mPidsSelfLocked) {
11704                boolean printed = false;
11705                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11706                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11707                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11708                        continue;
11709                    }
11710                    if (!printed) {
11711                        if (needSep) pw.println();
11712                        needSep = true;
11713                        pw.println("  PID mappings:");
11714                        printed = true;
11715                        printedAnything = true;
11716                    }
11717                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11718                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11719                }
11720            }
11721        }
11722
11723        if (mForegroundProcesses.size() > 0) {
11724            synchronized (mPidsSelfLocked) {
11725                boolean printed = false;
11726                for (int i=0; i<mForegroundProcesses.size(); i++) {
11727                    ProcessRecord r = mPidsSelfLocked.get(
11728                            mForegroundProcesses.valueAt(i).pid);
11729                    if (dumpPackage != null && (r == null
11730                            || !r.pkgList.containsKey(dumpPackage))) {
11731                        continue;
11732                    }
11733                    if (!printed) {
11734                        if (needSep) pw.println();
11735                        needSep = true;
11736                        pw.println("  Foreground Processes:");
11737                        printed = true;
11738                        printedAnything = true;
11739                    }
11740                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11741                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11742                }
11743            }
11744        }
11745
11746        if (mPersistentStartingProcesses.size() > 0) {
11747            if (needSep) pw.println();
11748            needSep = true;
11749            printedAnything = true;
11750            pw.println("  Persisent processes that are starting:");
11751            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11752                    "Starting Norm", "Restarting PERS", dumpPackage);
11753        }
11754
11755        if (mRemovedProcesses.size() > 0) {
11756            if (needSep) pw.println();
11757            needSep = true;
11758            printedAnything = true;
11759            pw.println("  Processes that are being removed:");
11760            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11761                    "Removed Norm", "Removed PERS", dumpPackage);
11762        }
11763
11764        if (mProcessesOnHold.size() > 0) {
11765            if (needSep) pw.println();
11766            needSep = true;
11767            printedAnything = true;
11768            pw.println("  Processes that are on old until the system is ready:");
11769            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11770                    "OnHold Norm", "OnHold PERS", dumpPackage);
11771        }
11772
11773        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11774
11775        if (mProcessCrashTimes.getMap().size() > 0) {
11776            boolean printed = false;
11777            long now = SystemClock.uptimeMillis();
11778            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11779            final int NP = pmap.size();
11780            for (int ip=0; ip<NP; ip++) {
11781                String pname = pmap.keyAt(ip);
11782                SparseArray<Long> uids = pmap.valueAt(ip);
11783                final int N = uids.size();
11784                for (int i=0; i<N; i++) {
11785                    int puid = uids.keyAt(i);
11786                    ProcessRecord r = mProcessNames.get(pname, puid);
11787                    if (dumpPackage != null && (r == null
11788                            || !r.pkgList.containsKey(dumpPackage))) {
11789                        continue;
11790                    }
11791                    if (!printed) {
11792                        if (needSep) pw.println();
11793                        needSep = true;
11794                        pw.println("  Time since processes crashed:");
11795                        printed = true;
11796                        printedAnything = true;
11797                    }
11798                    pw.print("    Process "); pw.print(pname);
11799                            pw.print(" uid "); pw.print(puid);
11800                            pw.print(": last crashed ");
11801                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11802                            pw.println(" ago");
11803                }
11804            }
11805        }
11806
11807        if (mBadProcesses.getMap().size() > 0) {
11808            boolean printed = false;
11809            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11810            final int NP = pmap.size();
11811            for (int ip=0; ip<NP; ip++) {
11812                String pname = pmap.keyAt(ip);
11813                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11814                final int N = uids.size();
11815                for (int i=0; i<N; i++) {
11816                    int puid = uids.keyAt(i);
11817                    ProcessRecord r = mProcessNames.get(pname, puid);
11818                    if (dumpPackage != null && (r == null
11819                            || !r.pkgList.containsKey(dumpPackage))) {
11820                        continue;
11821                    }
11822                    if (!printed) {
11823                        if (needSep) pw.println();
11824                        needSep = true;
11825                        pw.println("  Bad processes:");
11826                        printedAnything = true;
11827                    }
11828                    BadProcessInfo info = uids.valueAt(i);
11829                    pw.print("    Bad process "); pw.print(pname);
11830                            pw.print(" uid "); pw.print(puid);
11831                            pw.print(": crashed at time "); pw.println(info.time);
11832                    if (info.shortMsg != null) {
11833                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11834                    }
11835                    if (info.longMsg != null) {
11836                        pw.print("      Long msg: "); pw.println(info.longMsg);
11837                    }
11838                    if (info.stack != null) {
11839                        pw.println("      Stack:");
11840                        int lastPos = 0;
11841                        for (int pos=0; pos<info.stack.length(); pos++) {
11842                            if (info.stack.charAt(pos) == '\n') {
11843                                pw.print("        ");
11844                                pw.write(info.stack, lastPos, pos-lastPos);
11845                                pw.println();
11846                                lastPos = pos+1;
11847                            }
11848                        }
11849                        if (lastPos < info.stack.length()) {
11850                            pw.print("        ");
11851                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11852                            pw.println();
11853                        }
11854                    }
11855                }
11856            }
11857        }
11858
11859        if (dumpPackage == null) {
11860            pw.println();
11861            needSep = false;
11862            pw.println("  mStartedUsers:");
11863            for (int i=0; i<mStartedUsers.size(); i++) {
11864                UserStartedState uss = mStartedUsers.valueAt(i);
11865                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11866                        pw.print(": "); uss.dump("", pw);
11867            }
11868            pw.print("  mStartedUserArray: [");
11869            for (int i=0; i<mStartedUserArray.length; i++) {
11870                if (i > 0) pw.print(", ");
11871                pw.print(mStartedUserArray[i]);
11872            }
11873            pw.println("]");
11874            pw.print("  mUserLru: [");
11875            for (int i=0; i<mUserLru.size(); i++) {
11876                if (i > 0) pw.print(", ");
11877                pw.print(mUserLru.get(i));
11878            }
11879            pw.println("]");
11880            if (dumpAll) {
11881                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11882            }
11883            synchronized (mUserProfileGroupIdsSelfLocked) {
11884                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11885                    pw.println("  mUserProfileGroupIds:");
11886                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11887                        pw.print("    User #");
11888                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11889                        pw.print(" -> profile #");
11890                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11891                    }
11892                }
11893            }
11894        }
11895        if (mHomeProcess != null && (dumpPackage == null
11896                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11897            if (needSep) {
11898                pw.println();
11899                needSep = false;
11900            }
11901            pw.println("  mHomeProcess: " + mHomeProcess);
11902        }
11903        if (mPreviousProcess != null && (dumpPackage == null
11904                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11905            if (needSep) {
11906                pw.println();
11907                needSep = false;
11908            }
11909            pw.println("  mPreviousProcess: " + mPreviousProcess);
11910        }
11911        if (dumpAll) {
11912            StringBuilder sb = new StringBuilder(128);
11913            sb.append("  mPreviousProcessVisibleTime: ");
11914            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11915            pw.println(sb);
11916        }
11917        if (mHeavyWeightProcess != null && (dumpPackage == null
11918                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11919            if (needSep) {
11920                pw.println();
11921                needSep = false;
11922            }
11923            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11924        }
11925        if (dumpPackage == null) {
11926            pw.println("  mConfiguration: " + mConfiguration);
11927        }
11928        if (dumpAll) {
11929            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11930            if (mCompatModePackages.getPackages().size() > 0) {
11931                boolean printed = false;
11932                for (Map.Entry<String, Integer> entry
11933                        : mCompatModePackages.getPackages().entrySet()) {
11934                    String pkg = entry.getKey();
11935                    int mode = entry.getValue();
11936                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11937                        continue;
11938                    }
11939                    if (!printed) {
11940                        pw.println("  mScreenCompatPackages:");
11941                        printed = true;
11942                    }
11943                    pw.print("    "); pw.print(pkg); pw.print(": ");
11944                            pw.print(mode); pw.println();
11945                }
11946            }
11947        }
11948        if (dumpPackage == null) {
11949            if (mSleeping || mWentToSleep || mLockScreenShown) {
11950                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11951                        + " mLockScreenShown " + mLockScreenShown);
11952            }
11953            if (mShuttingDown || mRunningVoice) {
11954                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11955            }
11956        }
11957        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11958                || mOrigWaitForDebugger) {
11959            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11960                    || dumpPackage.equals(mOrigDebugApp)) {
11961                if (needSep) {
11962                    pw.println();
11963                    needSep = false;
11964                }
11965                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11966                        + " mDebugTransient=" + mDebugTransient
11967                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11968            }
11969        }
11970        if (mOpenGlTraceApp != null) {
11971            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11972                if (needSep) {
11973                    pw.println();
11974                    needSep = false;
11975                }
11976                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11977            }
11978        }
11979        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11980                || mProfileFd != null) {
11981            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11982                if (needSep) {
11983                    pw.println();
11984                    needSep = false;
11985                }
11986                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11987                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11988                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11989                        + mAutoStopProfiler);
11990            }
11991        }
11992        if (dumpPackage == null) {
11993            if (mAlwaysFinishActivities || mController != null) {
11994                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11995                        + " mController=" + mController);
11996            }
11997            if (dumpAll) {
11998                pw.println("  Total persistent processes: " + numPers);
11999                pw.println("  mProcessesReady=" + mProcessesReady
12000                        + " mSystemReady=" + mSystemReady);
12001                pw.println("  mBooting=" + mBooting
12002                        + " mBooted=" + mBooted
12003                        + " mFactoryTest=" + mFactoryTest);
12004                pw.print("  mLastPowerCheckRealtime=");
12005                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12006                        pw.println("");
12007                pw.print("  mLastPowerCheckUptime=");
12008                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12009                        pw.println("");
12010                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12011                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12012                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12013                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12014                        + " (" + mLruProcesses.size() + " total)"
12015                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12016                        + " mNumServiceProcs=" + mNumServiceProcs
12017                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12018                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12019                        + " mLastMemoryLevel" + mLastMemoryLevel
12020                        + " mLastNumProcesses" + mLastNumProcesses);
12021                long now = SystemClock.uptimeMillis();
12022                pw.print("  mLastIdleTime=");
12023                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12024                        pw.print(" mLowRamSinceLastIdle=");
12025                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12026                        pw.println();
12027            }
12028        }
12029
12030        if (!printedAnything) {
12031            pw.println("  (nothing)");
12032        }
12033    }
12034
12035    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12036            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12037        if (mProcessesToGc.size() > 0) {
12038            boolean printed = false;
12039            long now = SystemClock.uptimeMillis();
12040            for (int i=0; i<mProcessesToGc.size(); i++) {
12041                ProcessRecord proc = mProcessesToGc.get(i);
12042                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12043                    continue;
12044                }
12045                if (!printed) {
12046                    if (needSep) pw.println();
12047                    needSep = true;
12048                    pw.println("  Processes that are waiting to GC:");
12049                    printed = true;
12050                }
12051                pw.print("    Process "); pw.println(proc);
12052                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12053                        pw.print(", last gced=");
12054                        pw.print(now-proc.lastRequestedGc);
12055                        pw.print(" ms ago, last lowMem=");
12056                        pw.print(now-proc.lastLowMemory);
12057                        pw.println(" ms ago");
12058
12059            }
12060        }
12061        return needSep;
12062    }
12063
12064    void printOomLevel(PrintWriter pw, String name, int adj) {
12065        pw.print("    ");
12066        if (adj >= 0) {
12067            pw.print(' ');
12068            if (adj < 10) pw.print(' ');
12069        } else {
12070            if (adj > -10) pw.print(' ');
12071        }
12072        pw.print(adj);
12073        pw.print(": ");
12074        pw.print(name);
12075        pw.print(" (");
12076        pw.print(mProcessList.getMemLevel(adj)/1024);
12077        pw.println(" kB)");
12078    }
12079
12080    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12081            int opti, boolean dumpAll) {
12082        boolean needSep = false;
12083
12084        if (mLruProcesses.size() > 0) {
12085            if (needSep) pw.println();
12086            needSep = true;
12087            pw.println("  OOM levels:");
12088            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12089            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12090            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12091            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12092            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12093            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12094            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12095            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12096            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12097            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12098            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12099            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12100            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12101
12102            if (needSep) pw.println();
12103            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12104                    pw.print(" total, non-act at ");
12105                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12106                    pw.print(", non-svc at ");
12107                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12108                    pw.println("):");
12109            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12110            needSep = true;
12111        }
12112
12113        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12114
12115        pw.println();
12116        pw.println("  mHomeProcess: " + mHomeProcess);
12117        pw.println("  mPreviousProcess: " + mPreviousProcess);
12118        if (mHeavyWeightProcess != null) {
12119            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12120        }
12121
12122        return true;
12123    }
12124
12125    /**
12126     * There are three ways to call this:
12127     *  - no provider specified: dump all the providers
12128     *  - a flattened component name that matched an existing provider was specified as the
12129     *    first arg: dump that one provider
12130     *  - the first arg isn't the flattened component name of an existing provider:
12131     *    dump all providers whose component contains the first arg as a substring
12132     */
12133    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12134            int opti, boolean dumpAll) {
12135        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12136    }
12137
12138    static class ItemMatcher {
12139        ArrayList<ComponentName> components;
12140        ArrayList<String> strings;
12141        ArrayList<Integer> objects;
12142        boolean all;
12143
12144        ItemMatcher() {
12145            all = true;
12146        }
12147
12148        void build(String name) {
12149            ComponentName componentName = ComponentName.unflattenFromString(name);
12150            if (componentName != null) {
12151                if (components == null) {
12152                    components = new ArrayList<ComponentName>();
12153                }
12154                components.add(componentName);
12155                all = false;
12156            } else {
12157                int objectId = 0;
12158                // Not a '/' separated full component name; maybe an object ID?
12159                try {
12160                    objectId = Integer.parseInt(name, 16);
12161                    if (objects == null) {
12162                        objects = new ArrayList<Integer>();
12163                    }
12164                    objects.add(objectId);
12165                    all = false;
12166                } catch (RuntimeException e) {
12167                    // Not an integer; just do string match.
12168                    if (strings == null) {
12169                        strings = new ArrayList<String>();
12170                    }
12171                    strings.add(name);
12172                    all = false;
12173                }
12174            }
12175        }
12176
12177        int build(String[] args, int opti) {
12178            for (; opti<args.length; opti++) {
12179                String name = args[opti];
12180                if ("--".equals(name)) {
12181                    return opti+1;
12182                }
12183                build(name);
12184            }
12185            return opti;
12186        }
12187
12188        boolean match(Object object, ComponentName comp) {
12189            if (all) {
12190                return true;
12191            }
12192            if (components != null) {
12193                for (int i=0; i<components.size(); i++) {
12194                    if (components.get(i).equals(comp)) {
12195                        return true;
12196                    }
12197                }
12198            }
12199            if (objects != null) {
12200                for (int i=0; i<objects.size(); i++) {
12201                    if (System.identityHashCode(object) == objects.get(i)) {
12202                        return true;
12203                    }
12204                }
12205            }
12206            if (strings != null) {
12207                String flat = comp.flattenToString();
12208                for (int i=0; i<strings.size(); i++) {
12209                    if (flat.contains(strings.get(i))) {
12210                        return true;
12211                    }
12212                }
12213            }
12214            return false;
12215        }
12216    }
12217
12218    /**
12219     * There are three things that cmd can be:
12220     *  - a flattened component name that matches an existing activity
12221     *  - the cmd arg isn't the flattened component name of an existing activity:
12222     *    dump all activity whose component contains the cmd as a substring
12223     *  - A hex number of the ActivityRecord object instance.
12224     */
12225    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12226            int opti, boolean dumpAll) {
12227        ArrayList<ActivityRecord> activities;
12228
12229        synchronized (this) {
12230            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12231        }
12232
12233        if (activities.size() <= 0) {
12234            return false;
12235        }
12236
12237        String[] newArgs = new String[args.length - opti];
12238        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12239
12240        TaskRecord lastTask = null;
12241        boolean needSep = false;
12242        for (int i=activities.size()-1; i>=0; i--) {
12243            ActivityRecord r = activities.get(i);
12244            if (needSep) {
12245                pw.println();
12246            }
12247            needSep = true;
12248            synchronized (this) {
12249                if (lastTask != r.task) {
12250                    lastTask = r.task;
12251                    pw.print("TASK "); pw.print(lastTask.affinity);
12252                            pw.print(" id="); pw.println(lastTask.taskId);
12253                    if (dumpAll) {
12254                        lastTask.dump(pw, "  ");
12255                    }
12256                }
12257            }
12258            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12259        }
12260        return true;
12261    }
12262
12263    /**
12264     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12265     * there is a thread associated with the activity.
12266     */
12267    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12268            final ActivityRecord r, String[] args, boolean dumpAll) {
12269        String innerPrefix = prefix + "  ";
12270        synchronized (this) {
12271            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12272                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12273                    pw.print(" pid=");
12274                    if (r.app != null) pw.println(r.app.pid);
12275                    else pw.println("(not running)");
12276            if (dumpAll) {
12277                r.dump(pw, innerPrefix);
12278            }
12279        }
12280        if (r.app != null && r.app.thread != null) {
12281            // flush anything that is already in the PrintWriter since the thread is going
12282            // to write to the file descriptor directly
12283            pw.flush();
12284            try {
12285                TransferPipe tp = new TransferPipe();
12286                try {
12287                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12288                            r.appToken, innerPrefix, args);
12289                    tp.go(fd);
12290                } finally {
12291                    tp.kill();
12292                }
12293            } catch (IOException e) {
12294                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12295            } catch (RemoteException e) {
12296                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12297            }
12298        }
12299    }
12300
12301    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12302            int opti, boolean dumpAll, String dumpPackage) {
12303        boolean needSep = false;
12304        boolean onlyHistory = false;
12305        boolean printedAnything = false;
12306
12307        if ("history".equals(dumpPackage)) {
12308            if (opti < args.length && "-s".equals(args[opti])) {
12309                dumpAll = false;
12310            }
12311            onlyHistory = true;
12312            dumpPackage = null;
12313        }
12314
12315        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12316        if (!onlyHistory && dumpAll) {
12317            if (mRegisteredReceivers.size() > 0) {
12318                boolean printed = false;
12319                Iterator it = mRegisteredReceivers.values().iterator();
12320                while (it.hasNext()) {
12321                    ReceiverList r = (ReceiverList)it.next();
12322                    if (dumpPackage != null && (r.app == null ||
12323                            !dumpPackage.equals(r.app.info.packageName))) {
12324                        continue;
12325                    }
12326                    if (!printed) {
12327                        pw.println("  Registered Receivers:");
12328                        needSep = true;
12329                        printed = true;
12330                        printedAnything = true;
12331                    }
12332                    pw.print("  * "); pw.println(r);
12333                    r.dump(pw, "    ");
12334                }
12335            }
12336
12337            if (mReceiverResolver.dump(pw, needSep ?
12338                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12339                    "    ", dumpPackage, false)) {
12340                needSep = true;
12341                printedAnything = true;
12342            }
12343        }
12344
12345        for (BroadcastQueue q : mBroadcastQueues) {
12346            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12347            printedAnything |= needSep;
12348        }
12349
12350        needSep = true;
12351
12352        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12353            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12354                if (needSep) {
12355                    pw.println();
12356                }
12357                needSep = true;
12358                printedAnything = true;
12359                pw.print("  Sticky broadcasts for user ");
12360                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12361                StringBuilder sb = new StringBuilder(128);
12362                for (Map.Entry<String, ArrayList<Intent>> ent
12363                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12364                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12365                    if (dumpAll) {
12366                        pw.println(":");
12367                        ArrayList<Intent> intents = ent.getValue();
12368                        final int N = intents.size();
12369                        for (int i=0; i<N; i++) {
12370                            sb.setLength(0);
12371                            sb.append("    Intent: ");
12372                            intents.get(i).toShortString(sb, false, true, false, false);
12373                            pw.println(sb.toString());
12374                            Bundle bundle = intents.get(i).getExtras();
12375                            if (bundle != null) {
12376                                pw.print("      ");
12377                                pw.println(bundle.toString());
12378                            }
12379                        }
12380                    } else {
12381                        pw.println("");
12382                    }
12383                }
12384            }
12385        }
12386
12387        if (!onlyHistory && dumpAll) {
12388            pw.println();
12389            for (BroadcastQueue queue : mBroadcastQueues) {
12390                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12391                        + queue.mBroadcastsScheduled);
12392            }
12393            pw.println("  mHandler:");
12394            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12395            needSep = true;
12396            printedAnything = true;
12397        }
12398
12399        if (!printedAnything) {
12400            pw.println("  (nothing)");
12401        }
12402    }
12403
12404    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12405            int opti, boolean dumpAll, String dumpPackage) {
12406        boolean needSep;
12407        boolean printedAnything = false;
12408
12409        ItemMatcher matcher = new ItemMatcher();
12410        matcher.build(args, opti);
12411
12412        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12413
12414        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12415        printedAnything |= needSep;
12416
12417        if (mLaunchingProviders.size() > 0) {
12418            boolean printed = false;
12419            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12420                ContentProviderRecord r = mLaunchingProviders.get(i);
12421                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12422                    continue;
12423                }
12424                if (!printed) {
12425                    if (needSep) pw.println();
12426                    needSep = true;
12427                    pw.println("  Launching content providers:");
12428                    printed = true;
12429                    printedAnything = true;
12430                }
12431                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12432                        pw.println(r);
12433            }
12434        }
12435
12436        if (mGrantedUriPermissions.size() > 0) {
12437            boolean printed = false;
12438            int dumpUid = -2;
12439            if (dumpPackage != null) {
12440                try {
12441                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12442                } catch (NameNotFoundException e) {
12443                    dumpUid = -1;
12444                }
12445            }
12446            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12447                int uid = mGrantedUriPermissions.keyAt(i);
12448                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12449                    continue;
12450                }
12451                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12452                if (!printed) {
12453                    if (needSep) pw.println();
12454                    needSep = true;
12455                    pw.println("  Granted Uri Permissions:");
12456                    printed = true;
12457                    printedAnything = true;
12458                }
12459                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12460                for (UriPermission perm : perms.values()) {
12461                    pw.print("    "); pw.println(perm);
12462                    if (dumpAll) {
12463                        perm.dump(pw, "      ");
12464                    }
12465                }
12466            }
12467        }
12468
12469        if (!printedAnything) {
12470            pw.println("  (nothing)");
12471        }
12472    }
12473
12474    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12475            int opti, boolean dumpAll, String dumpPackage) {
12476        boolean printed = false;
12477
12478        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12479
12480        if (mIntentSenderRecords.size() > 0) {
12481            Iterator<WeakReference<PendingIntentRecord>> it
12482                    = mIntentSenderRecords.values().iterator();
12483            while (it.hasNext()) {
12484                WeakReference<PendingIntentRecord> ref = it.next();
12485                PendingIntentRecord rec = ref != null ? ref.get(): null;
12486                if (dumpPackage != null && (rec == null
12487                        || !dumpPackage.equals(rec.key.packageName))) {
12488                    continue;
12489                }
12490                printed = true;
12491                if (rec != null) {
12492                    pw.print("  * "); pw.println(rec);
12493                    if (dumpAll) {
12494                        rec.dump(pw, "    ");
12495                    }
12496                } else {
12497                    pw.print("  * "); pw.println(ref);
12498                }
12499            }
12500        }
12501
12502        if (!printed) {
12503            pw.println("  (nothing)");
12504        }
12505    }
12506
12507    private static final int dumpProcessList(PrintWriter pw,
12508            ActivityManagerService service, List list,
12509            String prefix, String normalLabel, String persistentLabel,
12510            String dumpPackage) {
12511        int numPers = 0;
12512        final int N = list.size()-1;
12513        for (int i=N; i>=0; i--) {
12514            ProcessRecord r = (ProcessRecord)list.get(i);
12515            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12516                continue;
12517            }
12518            pw.println(String.format("%s%s #%2d: %s",
12519                    prefix, (r.persistent ? persistentLabel : normalLabel),
12520                    i, r.toString()));
12521            if (r.persistent) {
12522                numPers++;
12523            }
12524        }
12525        return numPers;
12526    }
12527
12528    private static final boolean dumpProcessOomList(PrintWriter pw,
12529            ActivityManagerService service, List<ProcessRecord> origList,
12530            String prefix, String normalLabel, String persistentLabel,
12531            boolean inclDetails, String dumpPackage) {
12532
12533        ArrayList<Pair<ProcessRecord, Integer>> list
12534                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12535        for (int i=0; i<origList.size(); i++) {
12536            ProcessRecord r = origList.get(i);
12537            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12538                continue;
12539            }
12540            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12541        }
12542
12543        if (list.size() <= 0) {
12544            return false;
12545        }
12546
12547        Comparator<Pair<ProcessRecord, Integer>> comparator
12548                = new Comparator<Pair<ProcessRecord, Integer>>() {
12549            @Override
12550            public int compare(Pair<ProcessRecord, Integer> object1,
12551                    Pair<ProcessRecord, Integer> object2) {
12552                if (object1.first.setAdj != object2.first.setAdj) {
12553                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12554                }
12555                if (object1.second.intValue() != object2.second.intValue()) {
12556                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12557                }
12558                return 0;
12559            }
12560        };
12561
12562        Collections.sort(list, comparator);
12563
12564        final long curRealtime = SystemClock.elapsedRealtime();
12565        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12566        final long curUptime = SystemClock.uptimeMillis();
12567        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12568
12569        for (int i=list.size()-1; i>=0; i--) {
12570            ProcessRecord r = list.get(i).first;
12571            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12572            char schedGroup;
12573            switch (r.setSchedGroup) {
12574                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12575                    schedGroup = 'B';
12576                    break;
12577                case Process.THREAD_GROUP_DEFAULT:
12578                    schedGroup = 'F';
12579                    break;
12580                default:
12581                    schedGroup = '?';
12582                    break;
12583            }
12584            char foreground;
12585            if (r.foregroundActivities) {
12586                foreground = 'A';
12587            } else if (r.foregroundServices) {
12588                foreground = 'S';
12589            } else {
12590                foreground = ' ';
12591            }
12592            String procState = ProcessList.makeProcStateString(r.curProcState);
12593            pw.print(prefix);
12594            pw.print(r.persistent ? persistentLabel : normalLabel);
12595            pw.print(" #");
12596            int num = (origList.size()-1)-list.get(i).second;
12597            if (num < 10) pw.print(' ');
12598            pw.print(num);
12599            pw.print(": ");
12600            pw.print(oomAdj);
12601            pw.print(' ');
12602            pw.print(schedGroup);
12603            pw.print('/');
12604            pw.print(foreground);
12605            pw.print('/');
12606            pw.print(procState);
12607            pw.print(" trm:");
12608            if (r.trimMemoryLevel < 10) pw.print(' ');
12609            pw.print(r.trimMemoryLevel);
12610            pw.print(' ');
12611            pw.print(r.toShortString());
12612            pw.print(" (");
12613            pw.print(r.adjType);
12614            pw.println(')');
12615            if (r.adjSource != null || r.adjTarget != null) {
12616                pw.print(prefix);
12617                pw.print("    ");
12618                if (r.adjTarget instanceof ComponentName) {
12619                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12620                } else if (r.adjTarget != null) {
12621                    pw.print(r.adjTarget.toString());
12622                } else {
12623                    pw.print("{null}");
12624                }
12625                pw.print("<=");
12626                if (r.adjSource instanceof ProcessRecord) {
12627                    pw.print("Proc{");
12628                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12629                    pw.println("}");
12630                } else if (r.adjSource != null) {
12631                    pw.println(r.adjSource.toString());
12632                } else {
12633                    pw.println("{null}");
12634                }
12635            }
12636            if (inclDetails) {
12637                pw.print(prefix);
12638                pw.print("    ");
12639                pw.print("oom: max="); pw.print(r.maxAdj);
12640                pw.print(" curRaw="); pw.print(r.curRawAdj);
12641                pw.print(" setRaw="); pw.print(r.setRawAdj);
12642                pw.print(" cur="); pw.print(r.curAdj);
12643                pw.print(" set="); pw.println(r.setAdj);
12644                pw.print(prefix);
12645                pw.print("    ");
12646                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12647                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12648                pw.print(" lastPss="); pw.print(r.lastPss);
12649                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12650                pw.print(prefix);
12651                pw.print("    ");
12652                pw.print("cached="); pw.print(r.cached);
12653                pw.print(" empty="); pw.print(r.empty);
12654                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12655
12656                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12657                    if (r.lastWakeTime != 0) {
12658                        long wtime;
12659                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12660                        synchronized (stats) {
12661                            wtime = stats.getProcessWakeTime(r.info.uid,
12662                                    r.pid, curRealtime);
12663                        }
12664                        long timeUsed = wtime - r.lastWakeTime;
12665                        pw.print(prefix);
12666                        pw.print("    ");
12667                        pw.print("keep awake over ");
12668                        TimeUtils.formatDuration(realtimeSince, pw);
12669                        pw.print(" used ");
12670                        TimeUtils.formatDuration(timeUsed, pw);
12671                        pw.print(" (");
12672                        pw.print((timeUsed*100)/realtimeSince);
12673                        pw.println("%)");
12674                    }
12675                    if (r.lastCpuTime != 0) {
12676                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12677                        pw.print(prefix);
12678                        pw.print("    ");
12679                        pw.print("run cpu over ");
12680                        TimeUtils.formatDuration(uptimeSince, pw);
12681                        pw.print(" used ");
12682                        TimeUtils.formatDuration(timeUsed, pw);
12683                        pw.print(" (");
12684                        pw.print((timeUsed*100)/uptimeSince);
12685                        pw.println("%)");
12686                    }
12687                }
12688            }
12689        }
12690        return true;
12691    }
12692
12693    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12694        ArrayList<ProcessRecord> procs;
12695        synchronized (this) {
12696            if (args != null && args.length > start
12697                    && args[start].charAt(0) != '-') {
12698                procs = new ArrayList<ProcessRecord>();
12699                int pid = -1;
12700                try {
12701                    pid = Integer.parseInt(args[start]);
12702                } catch (NumberFormatException e) {
12703                }
12704                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12705                    ProcessRecord proc = mLruProcesses.get(i);
12706                    if (proc.pid == pid) {
12707                        procs.add(proc);
12708                    } else if (proc.processName.equals(args[start])) {
12709                        procs.add(proc);
12710                    }
12711                }
12712                if (procs.size() <= 0) {
12713                    return null;
12714                }
12715            } else {
12716                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12717            }
12718        }
12719        return procs;
12720    }
12721
12722    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12723            PrintWriter pw, String[] args) {
12724        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12725        if (procs == null) {
12726            pw.println("No process found for: " + args[0]);
12727            return;
12728        }
12729
12730        long uptime = SystemClock.uptimeMillis();
12731        long realtime = SystemClock.elapsedRealtime();
12732        pw.println("Applications Graphics Acceleration Info:");
12733        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12734
12735        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12736            ProcessRecord r = procs.get(i);
12737            if (r.thread != null) {
12738                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12739                pw.flush();
12740                try {
12741                    TransferPipe tp = new TransferPipe();
12742                    try {
12743                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12744                        tp.go(fd);
12745                    } finally {
12746                        tp.kill();
12747                    }
12748                } catch (IOException e) {
12749                    pw.println("Failure while dumping the app: " + r);
12750                    pw.flush();
12751                } catch (RemoteException e) {
12752                    pw.println("Got a RemoteException while dumping the app " + r);
12753                    pw.flush();
12754                }
12755            }
12756        }
12757    }
12758
12759    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12760        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12761        if (procs == null) {
12762            pw.println("No process found for: " + args[0]);
12763            return;
12764        }
12765
12766        pw.println("Applications Database Info:");
12767
12768        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12769            ProcessRecord r = procs.get(i);
12770            if (r.thread != null) {
12771                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12772                pw.flush();
12773                try {
12774                    TransferPipe tp = new TransferPipe();
12775                    try {
12776                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12777                        tp.go(fd);
12778                    } finally {
12779                        tp.kill();
12780                    }
12781                } catch (IOException e) {
12782                    pw.println("Failure while dumping the app: " + r);
12783                    pw.flush();
12784                } catch (RemoteException e) {
12785                    pw.println("Got a RemoteException while dumping the app " + r);
12786                    pw.flush();
12787                }
12788            }
12789        }
12790    }
12791
12792    final static class MemItem {
12793        final boolean isProc;
12794        final String label;
12795        final String shortLabel;
12796        final long pss;
12797        final int id;
12798        final boolean hasActivities;
12799        ArrayList<MemItem> subitems;
12800
12801        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12802                boolean _hasActivities) {
12803            isProc = true;
12804            label = _label;
12805            shortLabel = _shortLabel;
12806            pss = _pss;
12807            id = _id;
12808            hasActivities = _hasActivities;
12809        }
12810
12811        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12812            isProc = false;
12813            label = _label;
12814            shortLabel = _shortLabel;
12815            pss = _pss;
12816            id = _id;
12817            hasActivities = false;
12818        }
12819    }
12820
12821    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12822            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12823        if (sort && !isCompact) {
12824            Collections.sort(items, new Comparator<MemItem>() {
12825                @Override
12826                public int compare(MemItem lhs, MemItem rhs) {
12827                    if (lhs.pss < rhs.pss) {
12828                        return 1;
12829                    } else if (lhs.pss > rhs.pss) {
12830                        return -1;
12831                    }
12832                    return 0;
12833                }
12834            });
12835        }
12836
12837        for (int i=0; i<items.size(); i++) {
12838            MemItem mi = items.get(i);
12839            if (!isCompact) {
12840                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12841            } else if (mi.isProc) {
12842                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12843                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12844                pw.println(mi.hasActivities ? ",a" : ",e");
12845            } else {
12846                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12847                pw.println(mi.pss);
12848            }
12849            if (mi.subitems != null) {
12850                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12851                        true, isCompact);
12852            }
12853        }
12854    }
12855
12856    // These are in KB.
12857    static final long[] DUMP_MEM_BUCKETS = new long[] {
12858        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12859        120*1024, 160*1024, 200*1024,
12860        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12861        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12862    };
12863
12864    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12865            boolean stackLike) {
12866        int start = label.lastIndexOf('.');
12867        if (start >= 0) start++;
12868        else start = 0;
12869        int end = label.length();
12870        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12871            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12872                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12873                out.append(bucket);
12874                out.append(stackLike ? "MB." : "MB ");
12875                out.append(label, start, end);
12876                return;
12877            }
12878        }
12879        out.append(memKB/1024);
12880        out.append(stackLike ? "MB." : "MB ");
12881        out.append(label, start, end);
12882    }
12883
12884    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12885            ProcessList.NATIVE_ADJ,
12886            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12887            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12888            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12889            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12890            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12891    };
12892    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12893            "Native",
12894            "System", "Persistent", "Foreground",
12895            "Visible", "Perceptible",
12896            "Heavy Weight", "Backup",
12897            "A Services", "Home",
12898            "Previous", "B Services", "Cached"
12899    };
12900    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12901            "native",
12902            "sys", "pers", "fore",
12903            "vis", "percept",
12904            "heavy", "backup",
12905            "servicea", "home",
12906            "prev", "serviceb", "cached"
12907    };
12908
12909    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12910            long realtime, boolean isCheckinRequest, boolean isCompact) {
12911        if (isCheckinRequest || isCompact) {
12912            // short checkin version
12913            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12914        } else {
12915            pw.println("Applications Memory Usage (kB):");
12916            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12917        }
12918    }
12919
12920    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12921            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12922        boolean dumpDetails = false;
12923        boolean dumpFullDetails = false;
12924        boolean dumpDalvik = false;
12925        boolean oomOnly = false;
12926        boolean isCompact = false;
12927        boolean localOnly = false;
12928
12929        int opti = 0;
12930        while (opti < args.length) {
12931            String opt = args[opti];
12932            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12933                break;
12934            }
12935            opti++;
12936            if ("-a".equals(opt)) {
12937                dumpDetails = true;
12938                dumpFullDetails = true;
12939                dumpDalvik = true;
12940            } else if ("-d".equals(opt)) {
12941                dumpDalvik = true;
12942            } else if ("-c".equals(opt)) {
12943                isCompact = true;
12944            } else if ("--oom".equals(opt)) {
12945                oomOnly = true;
12946            } else if ("--local".equals(opt)) {
12947                localOnly = true;
12948            } else if ("-h".equals(opt)) {
12949                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12950                pw.println("  -a: include all available information for each process.");
12951                pw.println("  -d: include dalvik details when dumping process details.");
12952                pw.println("  -c: dump in a compact machine-parseable representation.");
12953                pw.println("  --oom: only show processes organized by oom adj.");
12954                pw.println("  --local: only collect details locally, don't call process.");
12955                pw.println("If [process] is specified it can be the name or ");
12956                pw.println("pid of a specific process to dump.");
12957                return;
12958            } else {
12959                pw.println("Unknown argument: " + opt + "; use -h for help");
12960            }
12961        }
12962
12963        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12964        long uptime = SystemClock.uptimeMillis();
12965        long realtime = SystemClock.elapsedRealtime();
12966        final long[] tmpLong = new long[1];
12967
12968        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12969        if (procs == null) {
12970            // No Java processes.  Maybe they want to print a native process.
12971            if (args != null && args.length > opti
12972                    && args[opti].charAt(0) != '-') {
12973                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12974                        = new ArrayList<ProcessCpuTracker.Stats>();
12975                updateCpuStatsNow();
12976                int findPid = -1;
12977                try {
12978                    findPid = Integer.parseInt(args[opti]);
12979                } catch (NumberFormatException e) {
12980                }
12981                synchronized (mProcessCpuThread) {
12982                    final int N = mProcessCpuTracker.countStats();
12983                    for (int i=0; i<N; i++) {
12984                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12985                        if (st.pid == findPid || (st.baseName != null
12986                                && st.baseName.equals(args[opti]))) {
12987                            nativeProcs.add(st);
12988                        }
12989                    }
12990                }
12991                if (nativeProcs.size() > 0) {
12992                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12993                            isCompact);
12994                    Debug.MemoryInfo mi = null;
12995                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12996                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12997                        final int pid = r.pid;
12998                        if (!isCheckinRequest && dumpDetails) {
12999                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13000                        }
13001                        if (mi == null) {
13002                            mi = new Debug.MemoryInfo();
13003                        }
13004                        if (dumpDetails || (!brief && !oomOnly)) {
13005                            Debug.getMemoryInfo(pid, mi);
13006                        } else {
13007                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13008                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13009                        }
13010                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13011                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13012                        if (isCheckinRequest) {
13013                            pw.println();
13014                        }
13015                    }
13016                    return;
13017                }
13018            }
13019            pw.println("No process found for: " + args[opti]);
13020            return;
13021        }
13022
13023        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13024            dumpDetails = true;
13025        }
13026
13027        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13028
13029        String[] innerArgs = new String[args.length-opti];
13030        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13031
13032        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13033        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13034        long nativePss=0, dalvikPss=0, otherPss=0;
13035        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13036
13037        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13038        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13039                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13040
13041        long totalPss = 0;
13042        long cachedPss = 0;
13043
13044        Debug.MemoryInfo mi = null;
13045        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13046            final ProcessRecord r = procs.get(i);
13047            final IApplicationThread thread;
13048            final int pid;
13049            final int oomAdj;
13050            final boolean hasActivities;
13051            synchronized (this) {
13052                thread = r.thread;
13053                pid = r.pid;
13054                oomAdj = r.getSetAdjWithServices();
13055                hasActivities = r.activities.size() > 0;
13056            }
13057            if (thread != null) {
13058                if (!isCheckinRequest && dumpDetails) {
13059                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13060                }
13061                if (mi == null) {
13062                    mi = new Debug.MemoryInfo();
13063                }
13064                if (dumpDetails || (!brief && !oomOnly)) {
13065                    Debug.getMemoryInfo(pid, mi);
13066                } else {
13067                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13068                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13069                }
13070                if (dumpDetails) {
13071                    if (localOnly) {
13072                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13073                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13074                        if (isCheckinRequest) {
13075                            pw.println();
13076                        }
13077                    } else {
13078                        try {
13079                            pw.flush();
13080                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13081                                    dumpDalvik, innerArgs);
13082                        } catch (RemoteException e) {
13083                            if (!isCheckinRequest) {
13084                                pw.println("Got RemoteException!");
13085                                pw.flush();
13086                            }
13087                        }
13088                    }
13089                }
13090
13091                final long myTotalPss = mi.getTotalPss();
13092                final long myTotalUss = mi.getTotalUss();
13093
13094                synchronized (this) {
13095                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13096                        // Record this for posterity if the process has been stable.
13097                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13098                    }
13099                }
13100
13101                if (!isCheckinRequest && mi != null) {
13102                    totalPss += myTotalPss;
13103                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13104                            (hasActivities ? " / activities)" : ")"),
13105                            r.processName, myTotalPss, pid, hasActivities);
13106                    procMems.add(pssItem);
13107                    procMemsMap.put(pid, pssItem);
13108
13109                    nativePss += mi.nativePss;
13110                    dalvikPss += mi.dalvikPss;
13111                    otherPss += mi.otherPss;
13112                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13113                        long mem = mi.getOtherPss(j);
13114                        miscPss[j] += mem;
13115                        otherPss -= mem;
13116                    }
13117
13118                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13119                        cachedPss += myTotalPss;
13120                    }
13121
13122                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13123                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13124                                || oomIndex == (oomPss.length-1)) {
13125                            oomPss[oomIndex] += myTotalPss;
13126                            if (oomProcs[oomIndex] == null) {
13127                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13128                            }
13129                            oomProcs[oomIndex].add(pssItem);
13130                            break;
13131                        }
13132                    }
13133                }
13134            }
13135        }
13136
13137        long nativeProcTotalPss = 0;
13138
13139        if (!isCheckinRequest && procs.size() > 1) {
13140            // If we are showing aggregations, also look for native processes to
13141            // include so that our aggregations are more accurate.
13142            updateCpuStatsNow();
13143            synchronized (mProcessCpuThread) {
13144                final int N = mProcessCpuTracker.countStats();
13145                for (int i=0; i<N; i++) {
13146                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13147                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13148                        if (mi == null) {
13149                            mi = new Debug.MemoryInfo();
13150                        }
13151                        if (!brief && !oomOnly) {
13152                            Debug.getMemoryInfo(st.pid, mi);
13153                        } else {
13154                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13155                            mi.nativePrivateDirty = (int)tmpLong[0];
13156                        }
13157
13158                        final long myTotalPss = mi.getTotalPss();
13159                        totalPss += myTotalPss;
13160                        nativeProcTotalPss += myTotalPss;
13161
13162                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13163                                st.name, myTotalPss, st.pid, false);
13164                        procMems.add(pssItem);
13165
13166                        nativePss += mi.nativePss;
13167                        dalvikPss += mi.dalvikPss;
13168                        otherPss += mi.otherPss;
13169                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13170                            long mem = mi.getOtherPss(j);
13171                            miscPss[j] += mem;
13172                            otherPss -= mem;
13173                        }
13174                        oomPss[0] += myTotalPss;
13175                        if (oomProcs[0] == null) {
13176                            oomProcs[0] = new ArrayList<MemItem>();
13177                        }
13178                        oomProcs[0].add(pssItem);
13179                    }
13180                }
13181            }
13182
13183            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13184
13185            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13186            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13187            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13188            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13189                String label = Debug.MemoryInfo.getOtherLabel(j);
13190                catMems.add(new MemItem(label, label, miscPss[j], j));
13191            }
13192
13193            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13194            for (int j=0; j<oomPss.length; j++) {
13195                if (oomPss[j] != 0) {
13196                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13197                            : DUMP_MEM_OOM_LABEL[j];
13198                    MemItem item = new MemItem(label, label, oomPss[j],
13199                            DUMP_MEM_OOM_ADJ[j]);
13200                    item.subitems = oomProcs[j];
13201                    oomMems.add(item);
13202                }
13203            }
13204
13205            if (!brief && !oomOnly && !isCompact) {
13206                pw.println();
13207                pw.println("Total PSS by process:");
13208                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13209                pw.println();
13210            }
13211            if (!isCompact) {
13212                pw.println("Total PSS by OOM adjustment:");
13213            }
13214            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13215            if (!brief && !oomOnly) {
13216                PrintWriter out = categoryPw != null ? categoryPw : pw;
13217                if (!isCompact) {
13218                    out.println();
13219                    out.println("Total PSS by category:");
13220                }
13221                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13222            }
13223            if (!isCompact) {
13224                pw.println();
13225            }
13226            MemInfoReader memInfo = new MemInfoReader();
13227            memInfo.readMemInfo();
13228            if (nativeProcTotalPss > 0) {
13229                synchronized (this) {
13230                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13231                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13232                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13233                            nativeProcTotalPss);
13234                }
13235            }
13236            if (!brief) {
13237                if (!isCompact) {
13238                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13239                    pw.print(" kB (status ");
13240                    switch (mLastMemoryLevel) {
13241                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13242                            pw.println("normal)");
13243                            break;
13244                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13245                            pw.println("moderate)");
13246                            break;
13247                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13248                            pw.println("low)");
13249                            break;
13250                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13251                            pw.println("critical)");
13252                            break;
13253                        default:
13254                            pw.print(mLastMemoryLevel);
13255                            pw.println(")");
13256                            break;
13257                    }
13258                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13259                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13260                            pw.print(cachedPss); pw.print(" cached pss + ");
13261                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13262                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13263                } else {
13264                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13265                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13266                            + memInfo.getFreeSizeKb()); pw.print(",");
13267                    pw.println(totalPss - cachedPss);
13268                }
13269            }
13270            if (!isCompact) {
13271                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13272                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13273                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13274                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13275                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13276                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13277                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13278                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13279                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13280                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13281                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13282            }
13283            if (!brief) {
13284                if (memInfo.getZramTotalSizeKb() != 0) {
13285                    if (!isCompact) {
13286                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13287                                pw.print(" kB physical used for ");
13288                                pw.print(memInfo.getSwapTotalSizeKb()
13289                                        - memInfo.getSwapFreeSizeKb());
13290                                pw.print(" kB in swap (");
13291                                pw.print(memInfo.getSwapTotalSizeKb());
13292                                pw.println(" kB total swap)");
13293                    } else {
13294                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13295                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13296                                pw.println(memInfo.getSwapFreeSizeKb());
13297                    }
13298                }
13299                final int[] SINGLE_LONG_FORMAT = new int[] {
13300                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13301                };
13302                long[] longOut = new long[1];
13303                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13304                        SINGLE_LONG_FORMAT, null, longOut, null);
13305                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13306                longOut[0] = 0;
13307                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13308                        SINGLE_LONG_FORMAT, null, longOut, null);
13309                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13310                longOut[0] = 0;
13311                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13312                        SINGLE_LONG_FORMAT, null, longOut, null);
13313                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13314                longOut[0] = 0;
13315                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13316                        SINGLE_LONG_FORMAT, null, longOut, null);
13317                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13318                if (!isCompact) {
13319                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13320                        pw.print("      KSM: "); pw.print(sharing);
13321                                pw.print(" kB saved from shared ");
13322                                pw.print(shared); pw.println(" kB");
13323                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13324                                pw.print(voltile); pw.println(" kB volatile");
13325                    }
13326                    pw.print("   Tuning: ");
13327                    pw.print(ActivityManager.staticGetMemoryClass());
13328                    pw.print(" (large ");
13329                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13330                    pw.print("), oom ");
13331                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13332                    pw.print(" kB");
13333                    pw.print(", restore limit ");
13334                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13335                    pw.print(" kB");
13336                    if (ActivityManager.isLowRamDeviceStatic()) {
13337                        pw.print(" (low-ram)");
13338                    }
13339                    if (ActivityManager.isHighEndGfx()) {
13340                        pw.print(" (high-end-gfx)");
13341                    }
13342                    pw.println();
13343                } else {
13344                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13345                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13346                    pw.println(voltile);
13347                    pw.print("tuning,");
13348                    pw.print(ActivityManager.staticGetMemoryClass());
13349                    pw.print(',');
13350                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13351                    pw.print(',');
13352                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13353                    if (ActivityManager.isLowRamDeviceStatic()) {
13354                        pw.print(",low-ram");
13355                    }
13356                    if (ActivityManager.isHighEndGfx()) {
13357                        pw.print(",high-end-gfx");
13358                    }
13359                    pw.println();
13360                }
13361            }
13362        }
13363    }
13364
13365    /**
13366     * Searches array of arguments for the specified string
13367     * @param args array of argument strings
13368     * @param value value to search for
13369     * @return true if the value is contained in the array
13370     */
13371    private static boolean scanArgs(String[] args, String value) {
13372        if (args != null) {
13373            for (String arg : args) {
13374                if (value.equals(arg)) {
13375                    return true;
13376                }
13377            }
13378        }
13379        return false;
13380    }
13381
13382    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13383            ContentProviderRecord cpr, boolean always) {
13384        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13385
13386        if (!inLaunching || always) {
13387            synchronized (cpr) {
13388                cpr.launchingApp = null;
13389                cpr.notifyAll();
13390            }
13391            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13392            String names[] = cpr.info.authority.split(";");
13393            for (int j = 0; j < names.length; j++) {
13394                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13395            }
13396        }
13397
13398        for (int i=0; i<cpr.connections.size(); i++) {
13399            ContentProviderConnection conn = cpr.connections.get(i);
13400            if (conn.waiting) {
13401                // If this connection is waiting for the provider, then we don't
13402                // need to mess with its process unless we are always removing
13403                // or for some reason the provider is not currently launching.
13404                if (inLaunching && !always) {
13405                    continue;
13406                }
13407            }
13408            ProcessRecord capp = conn.client;
13409            conn.dead = true;
13410            if (conn.stableCount > 0) {
13411                if (!capp.persistent && capp.thread != null
13412                        && capp.pid != 0
13413                        && capp.pid != MY_PID) {
13414                    killUnneededProcessLocked(capp, "depends on provider "
13415                            + cpr.name.flattenToShortString()
13416                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13417                }
13418            } else if (capp.thread != null && conn.provider.provider != null) {
13419                try {
13420                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13421                } catch (RemoteException e) {
13422                }
13423                // In the protocol here, we don't expect the client to correctly
13424                // clean up this connection, we'll just remove it.
13425                cpr.connections.remove(i);
13426                conn.client.conProviders.remove(conn);
13427            }
13428        }
13429
13430        if (inLaunching && always) {
13431            mLaunchingProviders.remove(cpr);
13432        }
13433        return inLaunching;
13434    }
13435
13436    /**
13437     * Main code for cleaning up a process when it has gone away.  This is
13438     * called both as a result of the process dying, or directly when stopping
13439     * a process when running in single process mode.
13440     */
13441    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13442            boolean restarting, boolean allowRestart, int index) {
13443        if (index >= 0) {
13444            removeLruProcessLocked(app);
13445            ProcessList.remove(app.pid);
13446        }
13447
13448        mProcessesToGc.remove(app);
13449        mPendingPssProcesses.remove(app);
13450
13451        // Dismiss any open dialogs.
13452        if (app.crashDialog != null && !app.forceCrashReport) {
13453            app.crashDialog.dismiss();
13454            app.crashDialog = null;
13455        }
13456        if (app.anrDialog != null) {
13457            app.anrDialog.dismiss();
13458            app.anrDialog = null;
13459        }
13460        if (app.waitDialog != null) {
13461            app.waitDialog.dismiss();
13462            app.waitDialog = null;
13463        }
13464
13465        app.crashing = false;
13466        app.notResponding = false;
13467
13468        app.resetPackageList(mProcessStats);
13469        app.unlinkDeathRecipient();
13470        app.makeInactive(mProcessStats);
13471        app.waitingToKill = null;
13472        app.forcingToForeground = null;
13473        updateProcessForegroundLocked(app, false, false);
13474        app.foregroundActivities = false;
13475        app.hasShownUi = false;
13476        app.treatLikeActivity = false;
13477        app.hasAboveClient = false;
13478        app.hasClientActivities = false;
13479
13480        mServices.killServicesLocked(app, allowRestart);
13481
13482        boolean restart = false;
13483
13484        // Remove published content providers.
13485        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13486            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13487            final boolean always = app.bad || !allowRestart;
13488            if (removeDyingProviderLocked(app, cpr, always) || always) {
13489                // We left the provider in the launching list, need to
13490                // restart it.
13491                restart = true;
13492            }
13493
13494            cpr.provider = null;
13495            cpr.proc = null;
13496        }
13497        app.pubProviders.clear();
13498
13499        // Take care of any launching providers waiting for this process.
13500        if (checkAppInLaunchingProvidersLocked(app, false)) {
13501            restart = true;
13502        }
13503
13504        // Unregister from connected content providers.
13505        if (!app.conProviders.isEmpty()) {
13506            for (int i=0; i<app.conProviders.size(); i++) {
13507                ContentProviderConnection conn = app.conProviders.get(i);
13508                conn.provider.connections.remove(conn);
13509            }
13510            app.conProviders.clear();
13511        }
13512
13513        // At this point there may be remaining entries in mLaunchingProviders
13514        // where we were the only one waiting, so they are no longer of use.
13515        // Look for these and clean up if found.
13516        // XXX Commented out for now.  Trying to figure out a way to reproduce
13517        // the actual situation to identify what is actually going on.
13518        if (false) {
13519            for (int i=0; i<mLaunchingProviders.size(); i++) {
13520                ContentProviderRecord cpr = (ContentProviderRecord)
13521                        mLaunchingProviders.get(i);
13522                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13523                    synchronized (cpr) {
13524                        cpr.launchingApp = null;
13525                        cpr.notifyAll();
13526                    }
13527                }
13528            }
13529        }
13530
13531        skipCurrentReceiverLocked(app);
13532
13533        // Unregister any receivers.
13534        for (int i=app.receivers.size()-1; i>=0; i--) {
13535            removeReceiverLocked(app.receivers.valueAt(i));
13536        }
13537        app.receivers.clear();
13538
13539        // If the app is undergoing backup, tell the backup manager about it
13540        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13541            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13542                    + mBackupTarget.appInfo + " died during backup");
13543            try {
13544                IBackupManager bm = IBackupManager.Stub.asInterface(
13545                        ServiceManager.getService(Context.BACKUP_SERVICE));
13546                bm.agentDisconnected(app.info.packageName);
13547            } catch (RemoteException e) {
13548                // can't happen; backup manager is local
13549            }
13550        }
13551
13552        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13553            ProcessChangeItem item = mPendingProcessChanges.get(i);
13554            if (item.pid == app.pid) {
13555                mPendingProcessChanges.remove(i);
13556                mAvailProcessChanges.add(item);
13557            }
13558        }
13559        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13560
13561        // If the caller is restarting this app, then leave it in its
13562        // current lists and let the caller take care of it.
13563        if (restarting) {
13564            return;
13565        }
13566
13567        if (!app.persistent || app.isolated) {
13568            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13569                    "Removing non-persistent process during cleanup: " + app);
13570            mProcessNames.remove(app.processName, app.uid);
13571            mIsolatedProcesses.remove(app.uid);
13572            if (mHeavyWeightProcess == app) {
13573                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13574                        mHeavyWeightProcess.userId, 0));
13575                mHeavyWeightProcess = null;
13576            }
13577        } else if (!app.removed) {
13578            // This app is persistent, so we need to keep its record around.
13579            // If it is not already on the pending app list, add it there
13580            // and start a new process for it.
13581            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13582                mPersistentStartingProcesses.add(app);
13583                restart = true;
13584            }
13585        }
13586        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13587                "Clean-up removing on hold: " + app);
13588        mProcessesOnHold.remove(app);
13589
13590        if (app == mHomeProcess) {
13591            mHomeProcess = null;
13592        }
13593        if (app == mPreviousProcess) {
13594            mPreviousProcess = null;
13595        }
13596
13597        if (restart && !app.isolated) {
13598            // We have components that still need to be running in the
13599            // process, so re-launch it.
13600            mProcessNames.put(app.processName, app.uid, app);
13601            startProcessLocked(app, "restart", app.processName);
13602        } else if (app.pid > 0 && app.pid != MY_PID) {
13603            // Goodbye!
13604            boolean removed;
13605            synchronized (mPidsSelfLocked) {
13606                mPidsSelfLocked.remove(app.pid);
13607                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13608            }
13609            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13610            if (app.isolated) {
13611                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13612            }
13613            app.setPid(0);
13614        }
13615    }
13616
13617    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13618        // Look through the content providers we are waiting to have launched,
13619        // and if any run in this process then either schedule a restart of
13620        // the process or kill the client waiting for it if this process has
13621        // gone bad.
13622        int NL = mLaunchingProviders.size();
13623        boolean restart = false;
13624        for (int i=0; i<NL; i++) {
13625            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13626            if (cpr.launchingApp == app) {
13627                if (!alwaysBad && !app.bad) {
13628                    restart = true;
13629                } else {
13630                    removeDyingProviderLocked(app, cpr, true);
13631                    // cpr should have been removed from mLaunchingProviders
13632                    NL = mLaunchingProviders.size();
13633                    i--;
13634                }
13635            }
13636        }
13637        return restart;
13638    }
13639
13640    // =========================================================
13641    // SERVICES
13642    // =========================================================
13643
13644    @Override
13645    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13646            int flags) {
13647        enforceNotIsolatedCaller("getServices");
13648        synchronized (this) {
13649            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13650        }
13651    }
13652
13653    @Override
13654    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13655        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13656        synchronized (this) {
13657            return mServices.getRunningServiceControlPanelLocked(name);
13658        }
13659    }
13660
13661    @Override
13662    public ComponentName startService(IApplicationThread caller, Intent service,
13663            String resolvedType, int userId) {
13664        enforceNotIsolatedCaller("startService");
13665        // Refuse possible leaked file descriptors
13666        if (service != null && service.hasFileDescriptors() == true) {
13667            throw new IllegalArgumentException("File descriptors passed in Intent");
13668        }
13669
13670        if (DEBUG_SERVICE)
13671            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13672        synchronized(this) {
13673            final int callingPid = Binder.getCallingPid();
13674            final int callingUid = Binder.getCallingUid();
13675            final long origId = Binder.clearCallingIdentity();
13676            ComponentName res = mServices.startServiceLocked(caller, service,
13677                    resolvedType, callingPid, callingUid, userId);
13678            Binder.restoreCallingIdentity(origId);
13679            return res;
13680        }
13681    }
13682
13683    ComponentName startServiceInPackage(int uid,
13684            Intent service, String resolvedType, int userId) {
13685        synchronized(this) {
13686            if (DEBUG_SERVICE)
13687                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13688            final long origId = Binder.clearCallingIdentity();
13689            ComponentName res = mServices.startServiceLocked(null, service,
13690                    resolvedType, -1, uid, userId);
13691            Binder.restoreCallingIdentity(origId);
13692            return res;
13693        }
13694    }
13695
13696    @Override
13697    public int stopService(IApplicationThread caller, Intent service,
13698            String resolvedType, int userId) {
13699        enforceNotIsolatedCaller("stopService");
13700        // Refuse possible leaked file descriptors
13701        if (service != null && service.hasFileDescriptors() == true) {
13702            throw new IllegalArgumentException("File descriptors passed in Intent");
13703        }
13704
13705        synchronized(this) {
13706            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13707        }
13708    }
13709
13710    @Override
13711    public IBinder peekService(Intent service, String resolvedType) {
13712        enforceNotIsolatedCaller("peekService");
13713        // Refuse possible leaked file descriptors
13714        if (service != null && service.hasFileDescriptors() == true) {
13715            throw new IllegalArgumentException("File descriptors passed in Intent");
13716        }
13717        synchronized(this) {
13718            return mServices.peekServiceLocked(service, resolvedType);
13719        }
13720    }
13721
13722    @Override
13723    public boolean stopServiceToken(ComponentName className, IBinder token,
13724            int startId) {
13725        synchronized(this) {
13726            return mServices.stopServiceTokenLocked(className, token, startId);
13727        }
13728    }
13729
13730    @Override
13731    public void setServiceForeground(ComponentName className, IBinder token,
13732            int id, Notification notification, boolean removeNotification) {
13733        synchronized(this) {
13734            mServices.setServiceForegroundLocked(className, token, id, notification,
13735                    removeNotification);
13736        }
13737    }
13738
13739    @Override
13740    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13741            boolean requireFull, String name, String callerPackage) {
13742        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13743                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13744    }
13745
13746    int unsafeConvertIncomingUser(int userId) {
13747        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13748                ? mCurrentUserId : userId;
13749    }
13750
13751    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13752            int allowMode, String name, String callerPackage) {
13753        final int callingUserId = UserHandle.getUserId(callingUid);
13754        if (callingUserId == userId) {
13755            return userId;
13756        }
13757
13758        // Note that we may be accessing mCurrentUserId outside of a lock...
13759        // shouldn't be a big deal, if this is being called outside
13760        // of a locked context there is intrinsically a race with
13761        // the value the caller will receive and someone else changing it.
13762        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13763        // we will switch to the calling user if access to the current user fails.
13764        int targetUserId = unsafeConvertIncomingUser(userId);
13765
13766        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13767            final boolean allow;
13768            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13769                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13770                // If the caller has this permission, they always pass go.  And collect $200.
13771                allow = true;
13772            } else if (allowMode == ALLOW_FULL_ONLY) {
13773                // We require full access, sucks to be you.
13774                allow = false;
13775            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13776                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13777                // If the caller does not have either permission, they are always doomed.
13778                allow = false;
13779            } else if (allowMode == ALLOW_NON_FULL) {
13780                // We are blanket allowing non-full access, you lucky caller!
13781                allow = true;
13782            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13783                // We may or may not allow this depending on whether the two users are
13784                // in the same profile.
13785                synchronized (mUserProfileGroupIdsSelfLocked) {
13786                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13787                            UserInfo.NO_PROFILE_GROUP_ID);
13788                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13789                            UserInfo.NO_PROFILE_GROUP_ID);
13790                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13791                            && callingProfile == targetProfile;
13792                }
13793            } else {
13794                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13795            }
13796            if (!allow) {
13797                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13798                    // In this case, they would like to just execute as their
13799                    // owner user instead of failing.
13800                    targetUserId = callingUserId;
13801                } else {
13802                    StringBuilder builder = new StringBuilder(128);
13803                    builder.append("Permission Denial: ");
13804                    builder.append(name);
13805                    if (callerPackage != null) {
13806                        builder.append(" from ");
13807                        builder.append(callerPackage);
13808                    }
13809                    builder.append(" asks to run as user ");
13810                    builder.append(userId);
13811                    builder.append(" but is calling from user ");
13812                    builder.append(UserHandle.getUserId(callingUid));
13813                    builder.append("; this requires ");
13814                    builder.append(INTERACT_ACROSS_USERS_FULL);
13815                    if (allowMode != ALLOW_FULL_ONLY) {
13816                        builder.append(" or ");
13817                        builder.append(INTERACT_ACROSS_USERS);
13818                    }
13819                    String msg = builder.toString();
13820                    Slog.w(TAG, msg);
13821                    throw new SecurityException(msg);
13822                }
13823            }
13824        }
13825        if (!allowAll && targetUserId < 0) {
13826            throw new IllegalArgumentException(
13827                    "Call does not support special user #" + targetUserId);
13828        }
13829        return targetUserId;
13830    }
13831
13832    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13833            String className, int flags) {
13834        boolean result = false;
13835        // For apps that don't have pre-defined UIDs, check for permission
13836        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13837            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13838                if (ActivityManager.checkUidPermission(
13839                        INTERACT_ACROSS_USERS,
13840                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13841                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13842                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13843                            + " requests FLAG_SINGLE_USER, but app does not hold "
13844                            + INTERACT_ACROSS_USERS;
13845                    Slog.w(TAG, msg);
13846                    throw new SecurityException(msg);
13847                }
13848                // Permission passed
13849                result = true;
13850            }
13851        } else if ("system".equals(componentProcessName)) {
13852            result = true;
13853        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
13854                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13855            // Phone app is allowed to export singleuser providers.
13856            result = true;
13857        } else {
13858            // App with pre-defined UID, check if it's a persistent app
13859            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13860        }
13861        if (DEBUG_MU) {
13862            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13863                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13864        }
13865        return result;
13866    }
13867
13868    /**
13869     * Checks to see if the caller is in the same app as the singleton
13870     * component, or the component is in a special app. It allows special apps
13871     * to export singleton components but prevents exporting singleton
13872     * components for regular apps.
13873     */
13874    boolean isValidSingletonCall(int callingUid, int componentUid) {
13875        int componentAppId = UserHandle.getAppId(componentUid);
13876        return UserHandle.isSameApp(callingUid, componentUid)
13877                || componentAppId == Process.SYSTEM_UID
13878                || componentAppId == Process.PHONE_UID
13879                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13880                        == PackageManager.PERMISSION_GRANTED;
13881    }
13882
13883    public int bindService(IApplicationThread caller, IBinder token,
13884            Intent service, String resolvedType,
13885            IServiceConnection connection, int flags, int userId) {
13886        enforceNotIsolatedCaller("bindService");
13887        // Refuse possible leaked file descriptors
13888        if (service != null && service.hasFileDescriptors() == true) {
13889            throw new IllegalArgumentException("File descriptors passed in Intent");
13890        }
13891
13892        synchronized(this) {
13893            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13894                    connection, flags, userId);
13895        }
13896    }
13897
13898    public boolean unbindService(IServiceConnection connection) {
13899        synchronized (this) {
13900            return mServices.unbindServiceLocked(connection);
13901        }
13902    }
13903
13904    public void publishService(IBinder token, Intent intent, IBinder service) {
13905        // Refuse possible leaked file descriptors
13906        if (intent != null && intent.hasFileDescriptors() == true) {
13907            throw new IllegalArgumentException("File descriptors passed in Intent");
13908        }
13909
13910        synchronized(this) {
13911            if (!(token instanceof ServiceRecord)) {
13912                throw new IllegalArgumentException("Invalid service token");
13913            }
13914            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13915        }
13916    }
13917
13918    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13919        // Refuse possible leaked file descriptors
13920        if (intent != null && intent.hasFileDescriptors() == true) {
13921            throw new IllegalArgumentException("File descriptors passed in Intent");
13922        }
13923
13924        synchronized(this) {
13925            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13926        }
13927    }
13928
13929    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13930        synchronized(this) {
13931            if (!(token instanceof ServiceRecord)) {
13932                throw new IllegalArgumentException("Invalid service token");
13933            }
13934            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13935        }
13936    }
13937
13938    // =========================================================
13939    // BACKUP AND RESTORE
13940    // =========================================================
13941
13942    // Cause the target app to be launched if necessary and its backup agent
13943    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13944    // activity manager to announce its creation.
13945    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13946        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13947        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13948
13949        synchronized(this) {
13950            // !!! TODO: currently no check here that we're already bound
13951            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13952            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13953            synchronized (stats) {
13954                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13955            }
13956
13957            // Backup agent is now in use, its package can't be stopped.
13958            try {
13959                AppGlobals.getPackageManager().setPackageStoppedState(
13960                        app.packageName, false, UserHandle.getUserId(app.uid));
13961            } catch (RemoteException e) {
13962            } catch (IllegalArgumentException e) {
13963                Slog.w(TAG, "Failed trying to unstop package "
13964                        + app.packageName + ": " + e);
13965            }
13966
13967            BackupRecord r = new BackupRecord(ss, app, backupMode);
13968            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13969                    ? new ComponentName(app.packageName, app.backupAgentName)
13970                    : new ComponentName("android", "FullBackupAgent");
13971            // startProcessLocked() returns existing proc's record if it's already running
13972            ProcessRecord proc = startProcessLocked(app.processName, app,
13973                    false, 0, "backup", hostingName, false, false, false);
13974            if (proc == null) {
13975                Slog.e(TAG, "Unable to start backup agent process " + r);
13976                return false;
13977            }
13978
13979            r.app = proc;
13980            mBackupTarget = r;
13981            mBackupAppName = app.packageName;
13982
13983            // Try not to kill the process during backup
13984            updateOomAdjLocked(proc);
13985
13986            // If the process is already attached, schedule the creation of the backup agent now.
13987            // If it is not yet live, this will be done when it attaches to the framework.
13988            if (proc.thread != null) {
13989                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13990                try {
13991                    proc.thread.scheduleCreateBackupAgent(app,
13992                            compatibilityInfoForPackageLocked(app), backupMode);
13993                } catch (RemoteException e) {
13994                    // Will time out on the backup manager side
13995                }
13996            } else {
13997                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13998            }
13999            // Invariants: at this point, the target app process exists and the application
14000            // is either already running or in the process of coming up.  mBackupTarget and
14001            // mBackupAppName describe the app, so that when it binds back to the AM we
14002            // know that it's scheduled for a backup-agent operation.
14003        }
14004
14005        return true;
14006    }
14007
14008    @Override
14009    public void clearPendingBackup() {
14010        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14011        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14012
14013        synchronized (this) {
14014            mBackupTarget = null;
14015            mBackupAppName = null;
14016        }
14017    }
14018
14019    // A backup agent has just come up
14020    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14021        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14022                + " = " + agent);
14023
14024        synchronized(this) {
14025            if (!agentPackageName.equals(mBackupAppName)) {
14026                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14027                return;
14028            }
14029        }
14030
14031        long oldIdent = Binder.clearCallingIdentity();
14032        try {
14033            IBackupManager bm = IBackupManager.Stub.asInterface(
14034                    ServiceManager.getService(Context.BACKUP_SERVICE));
14035            bm.agentConnected(agentPackageName, agent);
14036        } catch (RemoteException e) {
14037            // can't happen; the backup manager service is local
14038        } catch (Exception e) {
14039            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14040            e.printStackTrace();
14041        } finally {
14042            Binder.restoreCallingIdentity(oldIdent);
14043        }
14044    }
14045
14046    // done with this agent
14047    public void unbindBackupAgent(ApplicationInfo appInfo) {
14048        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14049        if (appInfo == null) {
14050            Slog.w(TAG, "unbind backup agent for null app");
14051            return;
14052        }
14053
14054        synchronized(this) {
14055            try {
14056                if (mBackupAppName == null) {
14057                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14058                    return;
14059                }
14060
14061                if (!mBackupAppName.equals(appInfo.packageName)) {
14062                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14063                    return;
14064                }
14065
14066                // Not backing this app up any more; reset its OOM adjustment
14067                final ProcessRecord proc = mBackupTarget.app;
14068                updateOomAdjLocked(proc);
14069
14070                // If the app crashed during backup, 'thread' will be null here
14071                if (proc.thread != null) {
14072                    try {
14073                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14074                                compatibilityInfoForPackageLocked(appInfo));
14075                    } catch (Exception e) {
14076                        Slog.e(TAG, "Exception when unbinding backup agent:");
14077                        e.printStackTrace();
14078                    }
14079                }
14080            } finally {
14081                mBackupTarget = null;
14082                mBackupAppName = null;
14083            }
14084        }
14085    }
14086    // =========================================================
14087    // BROADCASTS
14088    // =========================================================
14089
14090    private final List getStickiesLocked(String action, IntentFilter filter,
14091            List cur, int userId) {
14092        final ContentResolver resolver = mContext.getContentResolver();
14093        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14094        if (stickies == null) {
14095            return cur;
14096        }
14097        final ArrayList<Intent> list = stickies.get(action);
14098        if (list == null) {
14099            return cur;
14100        }
14101        int N = list.size();
14102        for (int i=0; i<N; i++) {
14103            Intent intent = list.get(i);
14104            if (filter.match(resolver, intent, true, TAG) >= 0) {
14105                if (cur == null) {
14106                    cur = new ArrayList<Intent>();
14107                }
14108                cur.add(intent);
14109            }
14110        }
14111        return cur;
14112    }
14113
14114    boolean isPendingBroadcastProcessLocked(int pid) {
14115        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14116                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14117    }
14118
14119    void skipPendingBroadcastLocked(int pid) {
14120            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14121            for (BroadcastQueue queue : mBroadcastQueues) {
14122                queue.skipPendingBroadcastLocked(pid);
14123            }
14124    }
14125
14126    // The app just attached; send any pending broadcasts that it should receive
14127    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14128        boolean didSomething = false;
14129        for (BroadcastQueue queue : mBroadcastQueues) {
14130            didSomething |= queue.sendPendingBroadcastsLocked(app);
14131        }
14132        return didSomething;
14133    }
14134
14135    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14136            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14137        enforceNotIsolatedCaller("registerReceiver");
14138        int callingUid;
14139        int callingPid;
14140        synchronized(this) {
14141            ProcessRecord callerApp = null;
14142            if (caller != null) {
14143                callerApp = getRecordForAppLocked(caller);
14144                if (callerApp == null) {
14145                    throw new SecurityException(
14146                            "Unable to find app for caller " + caller
14147                            + " (pid=" + Binder.getCallingPid()
14148                            + ") when registering receiver " + receiver);
14149                }
14150                if (callerApp.info.uid != Process.SYSTEM_UID &&
14151                        !callerApp.pkgList.containsKey(callerPackage) &&
14152                        !"android".equals(callerPackage)) {
14153                    throw new SecurityException("Given caller package " + callerPackage
14154                            + " is not running in process " + callerApp);
14155                }
14156                callingUid = callerApp.info.uid;
14157                callingPid = callerApp.pid;
14158            } else {
14159                callerPackage = null;
14160                callingUid = Binder.getCallingUid();
14161                callingPid = Binder.getCallingPid();
14162            }
14163
14164            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14165                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14166
14167            List allSticky = null;
14168
14169            // Look for any matching sticky broadcasts...
14170            Iterator actions = filter.actionsIterator();
14171            if (actions != null) {
14172                while (actions.hasNext()) {
14173                    String action = (String)actions.next();
14174                    allSticky = getStickiesLocked(action, filter, allSticky,
14175                            UserHandle.USER_ALL);
14176                    allSticky = getStickiesLocked(action, filter, allSticky,
14177                            UserHandle.getUserId(callingUid));
14178                }
14179            } else {
14180                allSticky = getStickiesLocked(null, filter, allSticky,
14181                        UserHandle.USER_ALL);
14182                allSticky = getStickiesLocked(null, filter, allSticky,
14183                        UserHandle.getUserId(callingUid));
14184            }
14185
14186            // The first sticky in the list is returned directly back to
14187            // the client.
14188            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14189
14190            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14191                    + ": " + sticky);
14192
14193            if (receiver == null) {
14194                return sticky;
14195            }
14196
14197            ReceiverList rl
14198                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14199            if (rl == null) {
14200                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14201                        userId, receiver);
14202                if (rl.app != null) {
14203                    rl.app.receivers.add(rl);
14204                } else {
14205                    try {
14206                        receiver.asBinder().linkToDeath(rl, 0);
14207                    } catch (RemoteException e) {
14208                        return sticky;
14209                    }
14210                    rl.linkedToDeath = true;
14211                }
14212                mRegisteredReceivers.put(receiver.asBinder(), rl);
14213            } else if (rl.uid != callingUid) {
14214                throw new IllegalArgumentException(
14215                        "Receiver requested to register for uid " + callingUid
14216                        + " was previously registered for uid " + rl.uid);
14217            } else if (rl.pid != callingPid) {
14218                throw new IllegalArgumentException(
14219                        "Receiver requested to register for pid " + callingPid
14220                        + " was previously registered for pid " + rl.pid);
14221            } else if (rl.userId != userId) {
14222                throw new IllegalArgumentException(
14223                        "Receiver requested to register for user " + userId
14224                        + " was previously registered for user " + rl.userId);
14225            }
14226            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14227                    permission, callingUid, userId);
14228            rl.add(bf);
14229            if (!bf.debugCheck()) {
14230                Slog.w(TAG, "==> For Dynamic broadast");
14231            }
14232            mReceiverResolver.addFilter(bf);
14233
14234            // Enqueue broadcasts for all existing stickies that match
14235            // this filter.
14236            if (allSticky != null) {
14237                ArrayList receivers = new ArrayList();
14238                receivers.add(bf);
14239
14240                int N = allSticky.size();
14241                for (int i=0; i<N; i++) {
14242                    Intent intent = (Intent)allSticky.get(i);
14243                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14244                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14245                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14246                            null, null, false, true, true, -1);
14247                    queue.enqueueParallelBroadcastLocked(r);
14248                    queue.scheduleBroadcastsLocked();
14249                }
14250            }
14251
14252            return sticky;
14253        }
14254    }
14255
14256    public void unregisterReceiver(IIntentReceiver receiver) {
14257        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14258
14259        final long origId = Binder.clearCallingIdentity();
14260        try {
14261            boolean doTrim = false;
14262
14263            synchronized(this) {
14264                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14265                if (rl != null) {
14266                    if (rl.curBroadcast != null) {
14267                        BroadcastRecord r = rl.curBroadcast;
14268                        final boolean doNext = finishReceiverLocked(
14269                                receiver.asBinder(), r.resultCode, r.resultData,
14270                                r.resultExtras, r.resultAbort);
14271                        if (doNext) {
14272                            doTrim = true;
14273                            r.queue.processNextBroadcast(false);
14274                        }
14275                    }
14276
14277                    if (rl.app != null) {
14278                        rl.app.receivers.remove(rl);
14279                    }
14280                    removeReceiverLocked(rl);
14281                    if (rl.linkedToDeath) {
14282                        rl.linkedToDeath = false;
14283                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14284                    }
14285                }
14286            }
14287
14288            // If we actually concluded any broadcasts, we might now be able
14289            // to trim the recipients' apps from our working set
14290            if (doTrim) {
14291                trimApplications();
14292                return;
14293            }
14294
14295        } finally {
14296            Binder.restoreCallingIdentity(origId);
14297        }
14298    }
14299
14300    void removeReceiverLocked(ReceiverList rl) {
14301        mRegisteredReceivers.remove(rl.receiver.asBinder());
14302        int N = rl.size();
14303        for (int i=0; i<N; i++) {
14304            mReceiverResolver.removeFilter(rl.get(i));
14305        }
14306    }
14307
14308    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14309        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14310            ProcessRecord r = mLruProcesses.get(i);
14311            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14312                try {
14313                    r.thread.dispatchPackageBroadcast(cmd, packages);
14314                } catch (RemoteException ex) {
14315                }
14316            }
14317        }
14318    }
14319
14320    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14321            int[] users) {
14322        List<ResolveInfo> receivers = null;
14323        try {
14324            HashSet<ComponentName> singleUserReceivers = null;
14325            boolean scannedFirstReceivers = false;
14326            for (int user : users) {
14327                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14328                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14329                if (user != 0 && newReceivers != null) {
14330                    // If this is not the primary user, we need to check for
14331                    // any receivers that should be filtered out.
14332                    for (int i=0; i<newReceivers.size(); i++) {
14333                        ResolveInfo ri = newReceivers.get(i);
14334                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14335                            newReceivers.remove(i);
14336                            i--;
14337                        }
14338                    }
14339                }
14340                if (newReceivers != null && newReceivers.size() == 0) {
14341                    newReceivers = null;
14342                }
14343                if (receivers == null) {
14344                    receivers = newReceivers;
14345                } else if (newReceivers != null) {
14346                    // We need to concatenate the additional receivers
14347                    // found with what we have do far.  This would be easy,
14348                    // but we also need to de-dup any receivers that are
14349                    // singleUser.
14350                    if (!scannedFirstReceivers) {
14351                        // Collect any single user receivers we had already retrieved.
14352                        scannedFirstReceivers = true;
14353                        for (int i=0; i<receivers.size(); i++) {
14354                            ResolveInfo ri = receivers.get(i);
14355                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14356                                ComponentName cn = new ComponentName(
14357                                        ri.activityInfo.packageName, ri.activityInfo.name);
14358                                if (singleUserReceivers == null) {
14359                                    singleUserReceivers = new HashSet<ComponentName>();
14360                                }
14361                                singleUserReceivers.add(cn);
14362                            }
14363                        }
14364                    }
14365                    // Add the new results to the existing results, tracking
14366                    // and de-dupping single user receivers.
14367                    for (int i=0; i<newReceivers.size(); i++) {
14368                        ResolveInfo ri = newReceivers.get(i);
14369                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14370                            ComponentName cn = new ComponentName(
14371                                    ri.activityInfo.packageName, ri.activityInfo.name);
14372                            if (singleUserReceivers == null) {
14373                                singleUserReceivers = new HashSet<ComponentName>();
14374                            }
14375                            if (!singleUserReceivers.contains(cn)) {
14376                                singleUserReceivers.add(cn);
14377                                receivers.add(ri);
14378                            }
14379                        } else {
14380                            receivers.add(ri);
14381                        }
14382                    }
14383                }
14384            }
14385        } catch (RemoteException ex) {
14386            // pm is in same process, this will never happen.
14387        }
14388        return receivers;
14389    }
14390
14391    private final int broadcastIntentLocked(ProcessRecord callerApp,
14392            String callerPackage, Intent intent, String resolvedType,
14393            IIntentReceiver resultTo, int resultCode, String resultData,
14394            Bundle map, String requiredPermission, int appOp,
14395            boolean ordered, boolean sticky, int callingPid, int callingUid,
14396            int userId) {
14397        intent = new Intent(intent);
14398
14399        // By default broadcasts do not go to stopped apps.
14400        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14401
14402        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14403            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14404            + " ordered=" + ordered + " userid=" + userId);
14405        if ((resultTo != null) && !ordered) {
14406            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14407        }
14408
14409        userId = handleIncomingUser(callingPid, callingUid, userId,
14410                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14411
14412        // Make sure that the user who is receiving this broadcast is started.
14413        // If not, we will just skip it.
14414
14415
14416        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14417            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14418                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14419                Slog.w(TAG, "Skipping broadcast of " + intent
14420                        + ": user " + userId + " is stopped");
14421                return ActivityManager.BROADCAST_SUCCESS;
14422            }
14423        }
14424
14425        /*
14426         * Prevent non-system code (defined here to be non-persistent
14427         * processes) from sending protected broadcasts.
14428         */
14429        int callingAppId = UserHandle.getAppId(callingUid);
14430        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14431            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14432            || callingAppId == Process.NFC_UID || callingUid == 0) {
14433            // Always okay.
14434        } else if (callerApp == null || !callerApp.persistent) {
14435            try {
14436                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14437                        intent.getAction())) {
14438                    String msg = "Permission Denial: not allowed to send broadcast "
14439                            + intent.getAction() + " from pid="
14440                            + callingPid + ", uid=" + callingUid;
14441                    Slog.w(TAG, msg);
14442                    throw new SecurityException(msg);
14443                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14444                    // Special case for compatibility: we don't want apps to send this,
14445                    // but historically it has not been protected and apps may be using it
14446                    // to poke their own app widget.  So, instead of making it protected,
14447                    // just limit it to the caller.
14448                    if (callerApp == null) {
14449                        String msg = "Permission Denial: not allowed to send broadcast "
14450                                + intent.getAction() + " from unknown caller.";
14451                        Slog.w(TAG, msg);
14452                        throw new SecurityException(msg);
14453                    } else if (intent.getComponent() != null) {
14454                        // They are good enough to send to an explicit component...  verify
14455                        // it is being sent to the calling app.
14456                        if (!intent.getComponent().getPackageName().equals(
14457                                callerApp.info.packageName)) {
14458                            String msg = "Permission Denial: not allowed to send broadcast "
14459                                    + intent.getAction() + " to "
14460                                    + intent.getComponent().getPackageName() + " from "
14461                                    + callerApp.info.packageName;
14462                            Slog.w(TAG, msg);
14463                            throw new SecurityException(msg);
14464                        }
14465                    } else {
14466                        // Limit broadcast to their own package.
14467                        intent.setPackage(callerApp.info.packageName);
14468                    }
14469                }
14470            } catch (RemoteException e) {
14471                Slog.w(TAG, "Remote exception", e);
14472                return ActivityManager.BROADCAST_SUCCESS;
14473            }
14474        }
14475
14476        // Handle special intents: if this broadcast is from the package
14477        // manager about a package being removed, we need to remove all of
14478        // its activities from the history stack.
14479        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14480                intent.getAction());
14481        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14482                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14483                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14484                || uidRemoved) {
14485            if (checkComponentPermission(
14486                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14487                    callingPid, callingUid, -1, true)
14488                    == PackageManager.PERMISSION_GRANTED) {
14489                if (uidRemoved) {
14490                    final Bundle intentExtras = intent.getExtras();
14491                    final int uid = intentExtras != null
14492                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14493                    if (uid >= 0) {
14494                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14495                        synchronized (bs) {
14496                            bs.removeUidStatsLocked(uid);
14497                        }
14498                        mAppOpsService.uidRemoved(uid);
14499                    }
14500                } else {
14501                    // If resources are unavailable just force stop all
14502                    // those packages and flush the attribute cache as well.
14503                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14504                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14505                        if (list != null && (list.length > 0)) {
14506                            for (String pkg : list) {
14507                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14508                                        "storage unmount");
14509                            }
14510                            sendPackageBroadcastLocked(
14511                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14512                        }
14513                    } else {
14514                        Uri data = intent.getData();
14515                        String ssp;
14516                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14517                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14518                                    intent.getAction());
14519                            boolean fullUninstall = removed &&
14520                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14521                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14522                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14523                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14524                                        false, fullUninstall, userId,
14525                                        removed ? "pkg removed" : "pkg changed");
14526                            }
14527                            if (removed) {
14528                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14529                                        new String[] {ssp}, userId);
14530                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14531                                    mAppOpsService.packageRemoved(
14532                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14533
14534                                    // Remove all permissions granted from/to this package
14535                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14536                                }
14537                            }
14538                        }
14539                    }
14540                }
14541            } else {
14542                String msg = "Permission Denial: " + intent.getAction()
14543                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14544                        + ", uid=" + callingUid + ")"
14545                        + " requires "
14546                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14547                Slog.w(TAG, msg);
14548                throw new SecurityException(msg);
14549            }
14550
14551        // Special case for adding a package: by default turn on compatibility
14552        // mode.
14553        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14554            Uri data = intent.getData();
14555            String ssp;
14556            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14557                mCompatModePackages.handlePackageAddedLocked(ssp,
14558                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14559            }
14560        }
14561
14562        /*
14563         * If this is the time zone changed action, queue up a message that will reset the timezone
14564         * of all currently running processes. This message will get queued up before the broadcast
14565         * happens.
14566         */
14567        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14568            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14569        }
14570
14571        /*
14572         * If the user set the time, let all running processes know.
14573         */
14574        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14575            final int is24Hour = intent.getBooleanExtra(
14576                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14577            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14578        }
14579
14580        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14581            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14582        }
14583
14584        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14585            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14586            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14587        }
14588
14589        // Add to the sticky list if requested.
14590        if (sticky) {
14591            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14592                    callingPid, callingUid)
14593                    != PackageManager.PERMISSION_GRANTED) {
14594                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14595                        + callingPid + ", uid=" + callingUid
14596                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14597                Slog.w(TAG, msg);
14598                throw new SecurityException(msg);
14599            }
14600            if (requiredPermission != null) {
14601                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14602                        + " and enforce permission " + requiredPermission);
14603                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14604            }
14605            if (intent.getComponent() != null) {
14606                throw new SecurityException(
14607                        "Sticky broadcasts can't target a specific component");
14608            }
14609            // We use userId directly here, since the "all" target is maintained
14610            // as a separate set of sticky broadcasts.
14611            if (userId != UserHandle.USER_ALL) {
14612                // But first, if this is not a broadcast to all users, then
14613                // make sure it doesn't conflict with an existing broadcast to
14614                // all users.
14615                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14616                        UserHandle.USER_ALL);
14617                if (stickies != null) {
14618                    ArrayList<Intent> list = stickies.get(intent.getAction());
14619                    if (list != null) {
14620                        int N = list.size();
14621                        int i;
14622                        for (i=0; i<N; i++) {
14623                            if (intent.filterEquals(list.get(i))) {
14624                                throw new IllegalArgumentException(
14625                                        "Sticky broadcast " + intent + " for user "
14626                                        + userId + " conflicts with existing global broadcast");
14627                            }
14628                        }
14629                    }
14630                }
14631            }
14632            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14633            if (stickies == null) {
14634                stickies = new ArrayMap<String, ArrayList<Intent>>();
14635                mStickyBroadcasts.put(userId, stickies);
14636            }
14637            ArrayList<Intent> list = stickies.get(intent.getAction());
14638            if (list == null) {
14639                list = new ArrayList<Intent>();
14640                stickies.put(intent.getAction(), list);
14641            }
14642            int N = list.size();
14643            int i;
14644            for (i=0; i<N; i++) {
14645                if (intent.filterEquals(list.get(i))) {
14646                    // This sticky already exists, replace it.
14647                    list.set(i, new Intent(intent));
14648                    break;
14649                }
14650            }
14651            if (i >= N) {
14652                list.add(new Intent(intent));
14653            }
14654        }
14655
14656        int[] users;
14657        if (userId == UserHandle.USER_ALL) {
14658            // Caller wants broadcast to go to all started users.
14659            users = mStartedUserArray;
14660        } else {
14661            // Caller wants broadcast to go to one specific user.
14662            users = new int[] {userId};
14663        }
14664
14665        // Figure out who all will receive this broadcast.
14666        List receivers = null;
14667        List<BroadcastFilter> registeredReceivers = null;
14668        // Need to resolve the intent to interested receivers...
14669        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14670                 == 0) {
14671            receivers = collectReceiverComponents(intent, resolvedType, users);
14672        }
14673        if (intent.getComponent() == null) {
14674            registeredReceivers = mReceiverResolver.queryIntent(intent,
14675                    resolvedType, false, userId);
14676        }
14677
14678        final boolean replacePending =
14679                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14680
14681        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14682                + " replacePending=" + replacePending);
14683
14684        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14685        if (!ordered && NR > 0) {
14686            // If we are not serializing this broadcast, then send the
14687            // registered receivers separately so they don't wait for the
14688            // components to be launched.
14689            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14690            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14691                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14692                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14693                    ordered, sticky, false, userId);
14694            if (DEBUG_BROADCAST) Slog.v(
14695                    TAG, "Enqueueing parallel broadcast " + r);
14696            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14697            if (!replaced) {
14698                queue.enqueueParallelBroadcastLocked(r);
14699                queue.scheduleBroadcastsLocked();
14700            }
14701            registeredReceivers = null;
14702            NR = 0;
14703        }
14704
14705        // Merge into one list.
14706        int ir = 0;
14707        if (receivers != null) {
14708            // A special case for PACKAGE_ADDED: do not allow the package
14709            // being added to see this broadcast.  This prevents them from
14710            // using this as a back door to get run as soon as they are
14711            // installed.  Maybe in the future we want to have a special install
14712            // broadcast or such for apps, but we'd like to deliberately make
14713            // this decision.
14714            String skipPackages[] = null;
14715            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14716                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14717                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14718                Uri data = intent.getData();
14719                if (data != null) {
14720                    String pkgName = data.getSchemeSpecificPart();
14721                    if (pkgName != null) {
14722                        skipPackages = new String[] { pkgName };
14723                    }
14724                }
14725            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14726                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14727            }
14728            if (skipPackages != null && (skipPackages.length > 0)) {
14729                for (String skipPackage : skipPackages) {
14730                    if (skipPackage != null) {
14731                        int NT = receivers.size();
14732                        for (int it=0; it<NT; it++) {
14733                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14734                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14735                                receivers.remove(it);
14736                                it--;
14737                                NT--;
14738                            }
14739                        }
14740                    }
14741                }
14742            }
14743
14744            int NT = receivers != null ? receivers.size() : 0;
14745            int it = 0;
14746            ResolveInfo curt = null;
14747            BroadcastFilter curr = null;
14748            while (it < NT && ir < NR) {
14749                if (curt == null) {
14750                    curt = (ResolveInfo)receivers.get(it);
14751                }
14752                if (curr == null) {
14753                    curr = registeredReceivers.get(ir);
14754                }
14755                if (curr.getPriority() >= curt.priority) {
14756                    // Insert this broadcast record into the final list.
14757                    receivers.add(it, curr);
14758                    ir++;
14759                    curr = null;
14760                    it++;
14761                    NT++;
14762                } else {
14763                    // Skip to the next ResolveInfo in the final list.
14764                    it++;
14765                    curt = null;
14766                }
14767            }
14768        }
14769        while (ir < NR) {
14770            if (receivers == null) {
14771                receivers = new ArrayList();
14772            }
14773            receivers.add(registeredReceivers.get(ir));
14774            ir++;
14775        }
14776
14777        if ((receivers != null && receivers.size() > 0)
14778                || resultTo != null) {
14779            BroadcastQueue queue = broadcastQueueForIntent(intent);
14780            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14781                    callerPackage, callingPid, callingUid, resolvedType,
14782                    requiredPermission, appOp, receivers, resultTo, resultCode,
14783                    resultData, map, ordered, sticky, false, userId);
14784            if (DEBUG_BROADCAST) Slog.v(
14785                    TAG, "Enqueueing ordered broadcast " + r
14786                    + ": prev had " + queue.mOrderedBroadcasts.size());
14787            if (DEBUG_BROADCAST) {
14788                int seq = r.intent.getIntExtra("seq", -1);
14789                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14790            }
14791            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14792            if (!replaced) {
14793                queue.enqueueOrderedBroadcastLocked(r);
14794                queue.scheduleBroadcastsLocked();
14795            }
14796        }
14797
14798        return ActivityManager.BROADCAST_SUCCESS;
14799    }
14800
14801    final Intent verifyBroadcastLocked(Intent intent) {
14802        // Refuse possible leaked file descriptors
14803        if (intent != null && intent.hasFileDescriptors() == true) {
14804            throw new IllegalArgumentException("File descriptors passed in Intent");
14805        }
14806
14807        int flags = intent.getFlags();
14808
14809        if (!mProcessesReady) {
14810            // if the caller really truly claims to know what they're doing, go
14811            // ahead and allow the broadcast without launching any receivers
14812            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14813                intent = new Intent(intent);
14814                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14815            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14816                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14817                        + " before boot completion");
14818                throw new IllegalStateException("Cannot broadcast before boot completed");
14819            }
14820        }
14821
14822        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14823            throw new IllegalArgumentException(
14824                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14825        }
14826
14827        return intent;
14828    }
14829
14830    public final int broadcastIntent(IApplicationThread caller,
14831            Intent intent, String resolvedType, IIntentReceiver resultTo,
14832            int resultCode, String resultData, Bundle map,
14833            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14834        enforceNotIsolatedCaller("broadcastIntent");
14835        synchronized(this) {
14836            intent = verifyBroadcastLocked(intent);
14837
14838            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14839            final int callingPid = Binder.getCallingPid();
14840            final int callingUid = Binder.getCallingUid();
14841            final long origId = Binder.clearCallingIdentity();
14842            int res = broadcastIntentLocked(callerApp,
14843                    callerApp != null ? callerApp.info.packageName : null,
14844                    intent, resolvedType, resultTo,
14845                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14846                    callingPid, callingUid, userId);
14847            Binder.restoreCallingIdentity(origId);
14848            return res;
14849        }
14850    }
14851
14852    int broadcastIntentInPackage(String packageName, int uid,
14853            Intent intent, String resolvedType, IIntentReceiver resultTo,
14854            int resultCode, String resultData, Bundle map,
14855            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14856        synchronized(this) {
14857            intent = verifyBroadcastLocked(intent);
14858
14859            final long origId = Binder.clearCallingIdentity();
14860            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14861                    resultTo, resultCode, resultData, map, requiredPermission,
14862                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14863            Binder.restoreCallingIdentity(origId);
14864            return res;
14865        }
14866    }
14867
14868    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14869        // Refuse possible leaked file descriptors
14870        if (intent != null && intent.hasFileDescriptors() == true) {
14871            throw new IllegalArgumentException("File descriptors passed in Intent");
14872        }
14873
14874        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14875                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14876
14877        synchronized(this) {
14878            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14879                    != PackageManager.PERMISSION_GRANTED) {
14880                String msg = "Permission Denial: unbroadcastIntent() from pid="
14881                        + Binder.getCallingPid()
14882                        + ", uid=" + Binder.getCallingUid()
14883                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14884                Slog.w(TAG, msg);
14885                throw new SecurityException(msg);
14886            }
14887            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14888            if (stickies != null) {
14889                ArrayList<Intent> list = stickies.get(intent.getAction());
14890                if (list != null) {
14891                    int N = list.size();
14892                    int i;
14893                    for (i=0; i<N; i++) {
14894                        if (intent.filterEquals(list.get(i))) {
14895                            list.remove(i);
14896                            break;
14897                        }
14898                    }
14899                    if (list.size() <= 0) {
14900                        stickies.remove(intent.getAction());
14901                    }
14902                }
14903                if (stickies.size() <= 0) {
14904                    mStickyBroadcasts.remove(userId);
14905                }
14906            }
14907        }
14908    }
14909
14910    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14911            String resultData, Bundle resultExtras, boolean resultAbort) {
14912        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14913        if (r == null) {
14914            Slog.w(TAG, "finishReceiver called but not found on queue");
14915            return false;
14916        }
14917
14918        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14919    }
14920
14921    void backgroundServicesFinishedLocked(int userId) {
14922        for (BroadcastQueue queue : mBroadcastQueues) {
14923            queue.backgroundServicesFinishedLocked(userId);
14924        }
14925    }
14926
14927    public void finishReceiver(IBinder who, int resultCode, String resultData,
14928            Bundle resultExtras, boolean resultAbort) {
14929        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14930
14931        // Refuse possible leaked file descriptors
14932        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14933            throw new IllegalArgumentException("File descriptors passed in Bundle");
14934        }
14935
14936        final long origId = Binder.clearCallingIdentity();
14937        try {
14938            boolean doNext = false;
14939            BroadcastRecord r;
14940
14941            synchronized(this) {
14942                r = broadcastRecordForReceiverLocked(who);
14943                if (r != null) {
14944                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14945                        resultData, resultExtras, resultAbort, true);
14946                }
14947            }
14948
14949            if (doNext) {
14950                r.queue.processNextBroadcast(false);
14951            }
14952            trimApplications();
14953        } finally {
14954            Binder.restoreCallingIdentity(origId);
14955        }
14956    }
14957
14958    // =========================================================
14959    // INSTRUMENTATION
14960    // =========================================================
14961
14962    public boolean startInstrumentation(ComponentName className,
14963            String profileFile, int flags, Bundle arguments,
14964            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14965            int userId, String abiOverride) {
14966        enforceNotIsolatedCaller("startInstrumentation");
14967        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14968                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14969        // Refuse possible leaked file descriptors
14970        if (arguments != null && arguments.hasFileDescriptors()) {
14971            throw new IllegalArgumentException("File descriptors passed in Bundle");
14972        }
14973
14974        synchronized(this) {
14975            InstrumentationInfo ii = null;
14976            ApplicationInfo ai = null;
14977            try {
14978                ii = mContext.getPackageManager().getInstrumentationInfo(
14979                    className, STOCK_PM_FLAGS);
14980                ai = AppGlobals.getPackageManager().getApplicationInfo(
14981                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14982            } catch (PackageManager.NameNotFoundException e) {
14983            } catch (RemoteException e) {
14984            }
14985            if (ii == null) {
14986                reportStartInstrumentationFailure(watcher, className,
14987                        "Unable to find instrumentation info for: " + className);
14988                return false;
14989            }
14990            if (ai == null) {
14991                reportStartInstrumentationFailure(watcher, className,
14992                        "Unable to find instrumentation target package: " + ii.targetPackage);
14993                return false;
14994            }
14995
14996            int match = mContext.getPackageManager().checkSignatures(
14997                    ii.targetPackage, ii.packageName);
14998            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14999                String msg = "Permission Denial: starting instrumentation "
15000                        + className + " from pid="
15001                        + Binder.getCallingPid()
15002                        + ", uid=" + Binder.getCallingPid()
15003                        + " not allowed because package " + ii.packageName
15004                        + " does not have a signature matching the target "
15005                        + ii.targetPackage;
15006                reportStartInstrumentationFailure(watcher, className, msg);
15007                throw new SecurityException(msg);
15008            }
15009
15010            final long origId = Binder.clearCallingIdentity();
15011            // Instrumentation can kill and relaunch even persistent processes
15012            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15013                    "start instr");
15014            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15015            app.instrumentationClass = className;
15016            app.instrumentationInfo = ai;
15017            app.instrumentationProfileFile = profileFile;
15018            app.instrumentationArguments = arguments;
15019            app.instrumentationWatcher = watcher;
15020            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15021            app.instrumentationResultClass = className;
15022            Binder.restoreCallingIdentity(origId);
15023        }
15024
15025        return true;
15026    }
15027
15028    /**
15029     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15030     * error to the logs, but if somebody is watching, send the report there too.  This enables
15031     * the "am" command to report errors with more information.
15032     *
15033     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15034     * @param cn The component name of the instrumentation.
15035     * @param report The error report.
15036     */
15037    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15038            ComponentName cn, String report) {
15039        Slog.w(TAG, report);
15040        try {
15041            if (watcher != null) {
15042                Bundle results = new Bundle();
15043                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15044                results.putString("Error", report);
15045                watcher.instrumentationStatus(cn, -1, results);
15046            }
15047        } catch (RemoteException e) {
15048            Slog.w(TAG, e);
15049        }
15050    }
15051
15052    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15053        if (app.instrumentationWatcher != null) {
15054            try {
15055                // NOTE:  IInstrumentationWatcher *must* be oneway here
15056                app.instrumentationWatcher.instrumentationFinished(
15057                    app.instrumentationClass,
15058                    resultCode,
15059                    results);
15060            } catch (RemoteException e) {
15061            }
15062        }
15063        if (app.instrumentationUiAutomationConnection != null) {
15064            try {
15065                app.instrumentationUiAutomationConnection.shutdown();
15066            } catch (RemoteException re) {
15067                /* ignore */
15068            }
15069            // Only a UiAutomation can set this flag and now that
15070            // it is finished we make sure it is reset to its default.
15071            mUserIsMonkey = false;
15072        }
15073        app.instrumentationWatcher = null;
15074        app.instrumentationUiAutomationConnection = null;
15075        app.instrumentationClass = null;
15076        app.instrumentationInfo = null;
15077        app.instrumentationProfileFile = null;
15078        app.instrumentationArguments = null;
15079
15080        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15081                "finished inst");
15082    }
15083
15084    public void finishInstrumentation(IApplicationThread target,
15085            int resultCode, Bundle results) {
15086        int userId = UserHandle.getCallingUserId();
15087        // Refuse possible leaked file descriptors
15088        if (results != null && results.hasFileDescriptors()) {
15089            throw new IllegalArgumentException("File descriptors passed in Intent");
15090        }
15091
15092        synchronized(this) {
15093            ProcessRecord app = getRecordForAppLocked(target);
15094            if (app == null) {
15095                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15096                return;
15097            }
15098            final long origId = Binder.clearCallingIdentity();
15099            finishInstrumentationLocked(app, resultCode, results);
15100            Binder.restoreCallingIdentity(origId);
15101        }
15102    }
15103
15104    // =========================================================
15105    // CONFIGURATION
15106    // =========================================================
15107
15108    public ConfigurationInfo getDeviceConfigurationInfo() {
15109        ConfigurationInfo config = new ConfigurationInfo();
15110        synchronized (this) {
15111            config.reqTouchScreen = mConfiguration.touchscreen;
15112            config.reqKeyboardType = mConfiguration.keyboard;
15113            config.reqNavigation = mConfiguration.navigation;
15114            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15115                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15116                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15117            }
15118            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15119                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15120                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15121            }
15122            config.reqGlEsVersion = GL_ES_VERSION;
15123        }
15124        return config;
15125    }
15126
15127    ActivityStack getFocusedStack() {
15128        return mStackSupervisor.getFocusedStack();
15129    }
15130
15131    public Configuration getConfiguration() {
15132        Configuration ci;
15133        synchronized(this) {
15134            ci = new Configuration(mConfiguration);
15135        }
15136        return ci;
15137    }
15138
15139    public void updatePersistentConfiguration(Configuration values) {
15140        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15141                "updateConfiguration()");
15142        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15143                "updateConfiguration()");
15144        if (values == null) {
15145            throw new NullPointerException("Configuration must not be null");
15146        }
15147
15148        synchronized(this) {
15149            final long origId = Binder.clearCallingIdentity();
15150            updateConfigurationLocked(values, null, true, false);
15151            Binder.restoreCallingIdentity(origId);
15152        }
15153    }
15154
15155    public void updateConfiguration(Configuration values) {
15156        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15157                "updateConfiguration()");
15158
15159        synchronized(this) {
15160            if (values == null && mWindowManager != null) {
15161                // sentinel: fetch the current configuration from the window manager
15162                values = mWindowManager.computeNewConfiguration();
15163            }
15164
15165            if (mWindowManager != null) {
15166                mProcessList.applyDisplaySize(mWindowManager);
15167            }
15168
15169            final long origId = Binder.clearCallingIdentity();
15170            if (values != null) {
15171                Settings.System.clearConfiguration(values);
15172            }
15173            updateConfigurationLocked(values, null, false, false);
15174            Binder.restoreCallingIdentity(origId);
15175        }
15176    }
15177
15178    /**
15179     * Do either or both things: (1) change the current configuration, and (2)
15180     * make sure the given activity is running with the (now) current
15181     * configuration.  Returns true if the activity has been left running, or
15182     * false if <var>starting</var> is being destroyed to match the new
15183     * configuration.
15184     * @param persistent TODO
15185     */
15186    boolean updateConfigurationLocked(Configuration values,
15187            ActivityRecord starting, boolean persistent, boolean initLocale) {
15188        int changes = 0;
15189
15190        if (values != null) {
15191            Configuration newConfig = new Configuration(mConfiguration);
15192            changes = newConfig.updateFrom(values);
15193            if (changes != 0) {
15194                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15195                    Slog.i(TAG, "Updating configuration to: " + values);
15196                }
15197
15198                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15199
15200                if (values.locale != null && !initLocale) {
15201                    saveLocaleLocked(values.locale,
15202                                     !values.locale.equals(mConfiguration.locale),
15203                                     values.userSetLocale);
15204                }
15205
15206                mConfigurationSeq++;
15207                if (mConfigurationSeq <= 0) {
15208                    mConfigurationSeq = 1;
15209                }
15210                newConfig.seq = mConfigurationSeq;
15211                mConfiguration = newConfig;
15212                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15213                //mUsageStatsService.noteStartConfig(newConfig);
15214
15215                final Configuration configCopy = new Configuration(mConfiguration);
15216
15217                // TODO: If our config changes, should we auto dismiss any currently
15218                // showing dialogs?
15219                mShowDialogs = shouldShowDialogs(newConfig);
15220
15221                AttributeCache ac = AttributeCache.instance();
15222                if (ac != null) {
15223                    ac.updateConfiguration(configCopy);
15224                }
15225
15226                // Make sure all resources in our process are updated
15227                // right now, so that anyone who is going to retrieve
15228                // resource values after we return will be sure to get
15229                // the new ones.  This is especially important during
15230                // boot, where the first config change needs to guarantee
15231                // all resources have that config before following boot
15232                // code is executed.
15233                mSystemThread.applyConfigurationToResources(configCopy);
15234
15235                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15236                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15237                    msg.obj = new Configuration(configCopy);
15238                    mHandler.sendMessage(msg);
15239                }
15240
15241                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15242                    ProcessRecord app = mLruProcesses.get(i);
15243                    try {
15244                        if (app.thread != null) {
15245                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15246                                    + app.processName + " new config " + mConfiguration);
15247                            app.thread.scheduleConfigurationChanged(configCopy);
15248                        }
15249                    } catch (Exception e) {
15250                    }
15251                }
15252                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15253                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15254                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15255                        | Intent.FLAG_RECEIVER_FOREGROUND);
15256                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15257                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15258                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15259                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15260                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15261                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15262                    broadcastIntentLocked(null, null, intent,
15263                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15264                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15265                }
15266            }
15267        }
15268
15269        boolean kept = true;
15270        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15271        // mainStack is null during startup.
15272        if (mainStack != null) {
15273            if (changes != 0 && starting == null) {
15274                // If the configuration changed, and the caller is not already
15275                // in the process of starting an activity, then find the top
15276                // activity to check if its configuration needs to change.
15277                starting = mainStack.topRunningActivityLocked(null);
15278            }
15279
15280            if (starting != null) {
15281                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15282                // And we need to make sure at this point that all other activities
15283                // are made visible with the correct configuration.
15284                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15285            }
15286        }
15287
15288        if (values != null && mWindowManager != null) {
15289            mWindowManager.setNewConfiguration(mConfiguration);
15290        }
15291
15292        return kept;
15293    }
15294
15295    /**
15296     * Decide based on the configuration whether we should shouw the ANR,
15297     * crash, etc dialogs.  The idea is that if there is no affordnace to
15298     * press the on-screen buttons, we shouldn't show the dialog.
15299     *
15300     * A thought: SystemUI might also want to get told about this, the Power
15301     * dialog / global actions also might want different behaviors.
15302     */
15303    private static final boolean shouldShowDialogs(Configuration config) {
15304        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15305                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15306    }
15307
15308    /**
15309     * Save the locale.  You must be inside a synchronized (this) block.
15310     */
15311    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15312        if(isDiff) {
15313            SystemProperties.set("user.language", l.getLanguage());
15314            SystemProperties.set("user.region", l.getCountry());
15315        }
15316
15317        if(isPersist) {
15318            SystemProperties.set("persist.sys.language", l.getLanguage());
15319            SystemProperties.set("persist.sys.country", l.getCountry());
15320            SystemProperties.set("persist.sys.localevar", l.getVariant());
15321        }
15322    }
15323
15324    @Override
15325    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15326        ActivityRecord srec = ActivityRecord.forToken(token);
15327        return srec != null && srec.task.affinity != null &&
15328                srec.task.affinity.equals(destAffinity);
15329    }
15330
15331    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15332            Intent resultData) {
15333
15334        synchronized (this) {
15335            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15336            if (stack != null) {
15337                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15338            }
15339            return false;
15340        }
15341    }
15342
15343    public int getLaunchedFromUid(IBinder activityToken) {
15344        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15345        if (srec == null) {
15346            return -1;
15347        }
15348        return srec.launchedFromUid;
15349    }
15350
15351    public String getLaunchedFromPackage(IBinder activityToken) {
15352        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15353        if (srec == null) {
15354            return null;
15355        }
15356        return srec.launchedFromPackage;
15357    }
15358
15359    // =========================================================
15360    // LIFETIME MANAGEMENT
15361    // =========================================================
15362
15363    // Returns which broadcast queue the app is the current [or imminent] receiver
15364    // on, or 'null' if the app is not an active broadcast recipient.
15365    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15366        BroadcastRecord r = app.curReceiver;
15367        if (r != null) {
15368            return r.queue;
15369        }
15370
15371        // It's not the current receiver, but it might be starting up to become one
15372        synchronized (this) {
15373            for (BroadcastQueue queue : mBroadcastQueues) {
15374                r = queue.mPendingBroadcast;
15375                if (r != null && r.curApp == app) {
15376                    // found it; report which queue it's in
15377                    return queue;
15378                }
15379            }
15380        }
15381
15382        return null;
15383    }
15384
15385    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15386            boolean doingAll, long now) {
15387        if (mAdjSeq == app.adjSeq) {
15388            // This adjustment has already been computed.
15389            return app.curRawAdj;
15390        }
15391
15392        if (app.thread == null) {
15393            app.adjSeq = mAdjSeq;
15394            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15395            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15396            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15397        }
15398
15399        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15400        app.adjSource = null;
15401        app.adjTarget = null;
15402        app.empty = false;
15403        app.cached = false;
15404
15405        final int activitiesSize = app.activities.size();
15406
15407        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15408            // The max adjustment doesn't allow this app to be anything
15409            // below foreground, so it is not worth doing work for it.
15410            app.adjType = "fixed";
15411            app.adjSeq = mAdjSeq;
15412            app.curRawAdj = app.maxAdj;
15413            app.foregroundActivities = false;
15414            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15415            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15416            // System processes can do UI, and when they do we want to have
15417            // them trim their memory after the user leaves the UI.  To
15418            // facilitate this, here we need to determine whether or not it
15419            // is currently showing UI.
15420            app.systemNoUi = true;
15421            if (app == TOP_APP) {
15422                app.systemNoUi = false;
15423            } else if (activitiesSize > 0) {
15424                for (int j = 0; j < activitiesSize; j++) {
15425                    final ActivityRecord r = app.activities.get(j);
15426                    if (r.visible) {
15427                        app.systemNoUi = false;
15428                    }
15429                }
15430            }
15431            if (!app.systemNoUi) {
15432                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15433            }
15434            return (app.curAdj=app.maxAdj);
15435        }
15436
15437        app.systemNoUi = false;
15438
15439        // Determine the importance of the process, starting with most
15440        // important to least, and assign an appropriate OOM adjustment.
15441        int adj;
15442        int schedGroup;
15443        int procState;
15444        boolean foregroundActivities = false;
15445        BroadcastQueue queue;
15446        if (app == TOP_APP) {
15447            // The last app on the list is the foreground app.
15448            adj = ProcessList.FOREGROUND_APP_ADJ;
15449            schedGroup = Process.THREAD_GROUP_DEFAULT;
15450            app.adjType = "top-activity";
15451            foregroundActivities = true;
15452            procState = ActivityManager.PROCESS_STATE_TOP;
15453        } else if (app.instrumentationClass != null) {
15454            // Don't want to kill running instrumentation.
15455            adj = ProcessList.FOREGROUND_APP_ADJ;
15456            schedGroup = Process.THREAD_GROUP_DEFAULT;
15457            app.adjType = "instrumentation";
15458            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15459        } else if ((queue = isReceivingBroadcast(app)) != null) {
15460            // An app that is currently receiving a broadcast also
15461            // counts as being in the foreground for OOM killer purposes.
15462            // It's placed in a sched group based on the nature of the
15463            // broadcast as reflected by which queue it's active in.
15464            adj = ProcessList.FOREGROUND_APP_ADJ;
15465            schedGroup = (queue == mFgBroadcastQueue)
15466                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15467            app.adjType = "broadcast";
15468            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15469        } else if (app.executingServices.size() > 0) {
15470            // An app that is currently executing a service callback also
15471            // counts as being in the foreground.
15472            adj = ProcessList.FOREGROUND_APP_ADJ;
15473            schedGroup = app.execServicesFg ?
15474                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15475            app.adjType = "exec-service";
15476            procState = ActivityManager.PROCESS_STATE_SERVICE;
15477            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15478        } else {
15479            // As far as we know the process is empty.  We may change our mind later.
15480            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15481            // At this point we don't actually know the adjustment.  Use the cached adj
15482            // value that the caller wants us to.
15483            adj = cachedAdj;
15484            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15485            app.cached = true;
15486            app.empty = true;
15487            app.adjType = "cch-empty";
15488        }
15489
15490        // Examine all activities if not already foreground.
15491        if (!foregroundActivities && activitiesSize > 0) {
15492            for (int j = 0; j < activitiesSize; j++) {
15493                final ActivityRecord r = app.activities.get(j);
15494                if (r.app != app) {
15495                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15496                            + app + "?!?");
15497                    continue;
15498                }
15499                if (r.visible) {
15500                    // App has a visible activity; only upgrade adjustment.
15501                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15502                        adj = ProcessList.VISIBLE_APP_ADJ;
15503                        app.adjType = "visible";
15504                    }
15505                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15506                        procState = ActivityManager.PROCESS_STATE_TOP;
15507                    }
15508                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15509                    app.cached = false;
15510                    app.empty = false;
15511                    foregroundActivities = true;
15512                    break;
15513                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15514                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15515                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15516                        app.adjType = "pausing";
15517                    }
15518                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15519                        procState = ActivityManager.PROCESS_STATE_TOP;
15520                    }
15521                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15522                    app.cached = false;
15523                    app.empty = false;
15524                    foregroundActivities = true;
15525                } else if (r.state == ActivityState.STOPPING) {
15526                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15527                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15528                        app.adjType = "stopping";
15529                    }
15530                    // For the process state, we will at this point consider the
15531                    // process to be cached.  It will be cached either as an activity
15532                    // or empty depending on whether the activity is finishing.  We do
15533                    // this so that we can treat the process as cached for purposes of
15534                    // memory trimming (determing current memory level, trim command to
15535                    // send to process) since there can be an arbitrary number of stopping
15536                    // processes and they should soon all go into the cached state.
15537                    if (!r.finishing) {
15538                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15539                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15540                        }
15541                    }
15542                    app.cached = false;
15543                    app.empty = false;
15544                    foregroundActivities = true;
15545                } else {
15546                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15547                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15548                        app.adjType = "cch-act";
15549                    }
15550                }
15551            }
15552        }
15553
15554        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15555            if (app.foregroundServices) {
15556                // The user is aware of this app, so make it visible.
15557                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15558                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15559                app.cached = false;
15560                app.adjType = "fg-service";
15561                schedGroup = Process.THREAD_GROUP_DEFAULT;
15562            } else if (app.forcingToForeground != null) {
15563                // The user is aware of this app, so make it visible.
15564                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15565                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15566                app.cached = false;
15567                app.adjType = "force-fg";
15568                app.adjSource = app.forcingToForeground;
15569                schedGroup = Process.THREAD_GROUP_DEFAULT;
15570            }
15571        }
15572
15573        if (app == mHeavyWeightProcess) {
15574            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15575                // We don't want to kill the current heavy-weight process.
15576                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15577                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15578                app.cached = false;
15579                app.adjType = "heavy";
15580            }
15581            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15582                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15583            }
15584        }
15585
15586        if (app == mHomeProcess) {
15587            if (adj > ProcessList.HOME_APP_ADJ) {
15588                // This process is hosting what we currently consider to be the
15589                // home app, so we don't want to let it go into the background.
15590                adj = ProcessList.HOME_APP_ADJ;
15591                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15592                app.cached = false;
15593                app.adjType = "home";
15594            }
15595            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15596                procState = ActivityManager.PROCESS_STATE_HOME;
15597            }
15598        }
15599
15600        if (app == mPreviousProcess && app.activities.size() > 0) {
15601            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15602                // This was the previous process that showed UI to the user.
15603                // We want to try to keep it around more aggressively, to give
15604                // a good experience around switching between two apps.
15605                adj = ProcessList.PREVIOUS_APP_ADJ;
15606                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15607                app.cached = false;
15608                app.adjType = "previous";
15609            }
15610            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15611                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15612            }
15613        }
15614
15615        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15616                + " reason=" + app.adjType);
15617
15618        // By default, we use the computed adjustment.  It may be changed if
15619        // there are applications dependent on our services or providers, but
15620        // this gives us a baseline and makes sure we don't get into an
15621        // infinite recursion.
15622        app.adjSeq = mAdjSeq;
15623        app.curRawAdj = adj;
15624        app.hasStartedServices = false;
15625
15626        if (mBackupTarget != null && app == mBackupTarget.app) {
15627            // If possible we want to avoid killing apps while they're being backed up
15628            if (adj > ProcessList.BACKUP_APP_ADJ) {
15629                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15630                adj = ProcessList.BACKUP_APP_ADJ;
15631                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15632                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15633                }
15634                app.adjType = "backup";
15635                app.cached = false;
15636            }
15637            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15638                procState = ActivityManager.PROCESS_STATE_BACKUP;
15639            }
15640        }
15641
15642        boolean mayBeTop = false;
15643
15644        for (int is = app.services.size()-1;
15645                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15646                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15647                        || procState > ActivityManager.PROCESS_STATE_TOP);
15648                is--) {
15649            ServiceRecord s = app.services.valueAt(is);
15650            if (s.startRequested) {
15651                app.hasStartedServices = true;
15652                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15653                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15654                }
15655                if (app.hasShownUi && app != mHomeProcess) {
15656                    // If this process has shown some UI, let it immediately
15657                    // go to the LRU list because it may be pretty heavy with
15658                    // UI stuff.  We'll tag it with a label just to help
15659                    // debug and understand what is going on.
15660                    if (adj > ProcessList.SERVICE_ADJ) {
15661                        app.adjType = "cch-started-ui-services";
15662                    }
15663                } else {
15664                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15665                        // This service has seen some activity within
15666                        // recent memory, so we will keep its process ahead
15667                        // of the background processes.
15668                        if (adj > ProcessList.SERVICE_ADJ) {
15669                            adj = ProcessList.SERVICE_ADJ;
15670                            app.adjType = "started-services";
15671                            app.cached = false;
15672                        }
15673                    }
15674                    // If we have let the service slide into the background
15675                    // state, still have some text describing what it is doing
15676                    // even though the service no longer has an impact.
15677                    if (adj > ProcessList.SERVICE_ADJ) {
15678                        app.adjType = "cch-started-services";
15679                    }
15680                }
15681            }
15682            for (int conni = s.connections.size()-1;
15683                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15684                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15685                            || procState > ActivityManager.PROCESS_STATE_TOP);
15686                    conni--) {
15687                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15688                for (int i = 0;
15689                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15690                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15691                                || procState > ActivityManager.PROCESS_STATE_TOP);
15692                        i++) {
15693                    // XXX should compute this based on the max of
15694                    // all connected clients.
15695                    ConnectionRecord cr = clist.get(i);
15696                    if (cr.binding.client == app) {
15697                        // Binding to ourself is not interesting.
15698                        continue;
15699                    }
15700                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15701                        ProcessRecord client = cr.binding.client;
15702                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15703                                TOP_APP, doingAll, now);
15704                        int clientProcState = client.curProcState;
15705                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15706                            // If the other app is cached for any reason, for purposes here
15707                            // we are going to consider it empty.  The specific cached state
15708                            // doesn't propagate except under certain conditions.
15709                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15710                        }
15711                        String adjType = null;
15712                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15713                            // Not doing bind OOM management, so treat
15714                            // this guy more like a started service.
15715                            if (app.hasShownUi && app != mHomeProcess) {
15716                                // If this process has shown some UI, let it immediately
15717                                // go to the LRU list because it may be pretty heavy with
15718                                // UI stuff.  We'll tag it with a label just to help
15719                                // debug and understand what is going on.
15720                                if (adj > clientAdj) {
15721                                    adjType = "cch-bound-ui-services";
15722                                }
15723                                app.cached = false;
15724                                clientAdj = adj;
15725                                clientProcState = procState;
15726                            } else {
15727                                if (now >= (s.lastActivity
15728                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15729                                    // This service has not seen activity within
15730                                    // recent memory, so allow it to drop to the
15731                                    // LRU list if there is no other reason to keep
15732                                    // it around.  We'll also tag it with a label just
15733                                    // to help debug and undertand what is going on.
15734                                    if (adj > clientAdj) {
15735                                        adjType = "cch-bound-services";
15736                                    }
15737                                    clientAdj = adj;
15738                                }
15739                            }
15740                        }
15741                        if (adj > clientAdj) {
15742                            // If this process has recently shown UI, and
15743                            // the process that is binding to it is less
15744                            // important than being visible, then we don't
15745                            // care about the binding as much as we care
15746                            // about letting this process get into the LRU
15747                            // list to be killed and restarted if needed for
15748                            // memory.
15749                            if (app.hasShownUi && app != mHomeProcess
15750                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15751                                adjType = "cch-bound-ui-services";
15752                            } else {
15753                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15754                                        |Context.BIND_IMPORTANT)) != 0) {
15755                                    adj = clientAdj;
15756                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15757                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15758                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15759                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15760                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15761                                    adj = clientAdj;
15762                                } else {
15763                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15764                                        adj = ProcessList.VISIBLE_APP_ADJ;
15765                                    }
15766                                }
15767                                if (!client.cached) {
15768                                    app.cached = false;
15769                                }
15770                                adjType = "service";
15771                            }
15772                        }
15773                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15774                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15775                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15776                            }
15777                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15778                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15779                                    // Special handling of clients who are in the top state.
15780                                    // We *may* want to consider this process to be in the
15781                                    // top state as well, but only if there is not another
15782                                    // reason for it to be running.  Being on the top is a
15783                                    // special state, meaning you are specifically running
15784                                    // for the current top app.  If the process is already
15785                                    // running in the background for some other reason, it
15786                                    // is more important to continue considering it to be
15787                                    // in the background state.
15788                                    mayBeTop = true;
15789                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15790                                } else {
15791                                    // Special handling for above-top states (persistent
15792                                    // processes).  These should not bring the current process
15793                                    // into the top state, since they are not on top.  Instead
15794                                    // give them the best state after that.
15795                                    clientProcState =
15796                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15797                                }
15798                            }
15799                        } else {
15800                            if (clientProcState <
15801                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15802                                clientProcState =
15803                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15804                            }
15805                        }
15806                        if (procState > clientProcState) {
15807                            procState = clientProcState;
15808                        }
15809                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15810                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15811                            app.pendingUiClean = true;
15812                        }
15813                        if (adjType != null) {
15814                            app.adjType = adjType;
15815                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15816                                    .REASON_SERVICE_IN_USE;
15817                            app.adjSource = cr.binding.client;
15818                            app.adjSourceProcState = clientProcState;
15819                            app.adjTarget = s.name;
15820                        }
15821                    }
15822                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15823                        app.treatLikeActivity = true;
15824                    }
15825                    final ActivityRecord a = cr.activity;
15826                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15827                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15828                                (a.visible || a.state == ActivityState.RESUMED
15829                                 || a.state == ActivityState.PAUSING)) {
15830                            adj = ProcessList.FOREGROUND_APP_ADJ;
15831                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15832                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15833                            }
15834                            app.cached = false;
15835                            app.adjType = "service";
15836                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15837                                    .REASON_SERVICE_IN_USE;
15838                            app.adjSource = a;
15839                            app.adjSourceProcState = procState;
15840                            app.adjTarget = s.name;
15841                        }
15842                    }
15843                }
15844            }
15845        }
15846
15847        for (int provi = app.pubProviders.size()-1;
15848                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15849                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15850                        || procState > ActivityManager.PROCESS_STATE_TOP);
15851                provi--) {
15852            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15853            for (int i = cpr.connections.size()-1;
15854                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15855                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15856                            || procState > ActivityManager.PROCESS_STATE_TOP);
15857                    i--) {
15858                ContentProviderConnection conn = cpr.connections.get(i);
15859                ProcessRecord client = conn.client;
15860                if (client == app) {
15861                    // Being our own client is not interesting.
15862                    continue;
15863                }
15864                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15865                int clientProcState = client.curProcState;
15866                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15867                    // If the other app is cached for any reason, for purposes here
15868                    // we are going to consider it empty.
15869                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15870                }
15871                if (adj > clientAdj) {
15872                    if (app.hasShownUi && app != mHomeProcess
15873                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15874                        app.adjType = "cch-ui-provider";
15875                    } else {
15876                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15877                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15878                        app.adjType = "provider";
15879                    }
15880                    app.cached &= client.cached;
15881                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15882                            .REASON_PROVIDER_IN_USE;
15883                    app.adjSource = client;
15884                    app.adjSourceProcState = clientProcState;
15885                    app.adjTarget = cpr.name;
15886                }
15887                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15888                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15889                        // Special handling of clients who are in the top state.
15890                        // We *may* want to consider this process to be in the
15891                        // top state as well, but only if there is not another
15892                        // reason for it to be running.  Being on the top is a
15893                        // special state, meaning you are specifically running
15894                        // for the current top app.  If the process is already
15895                        // running in the background for some other reason, it
15896                        // is more important to continue considering it to be
15897                        // in the background state.
15898                        mayBeTop = true;
15899                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15900                    } else {
15901                        // Special handling for above-top states (persistent
15902                        // processes).  These should not bring the current process
15903                        // into the top state, since they are not on top.  Instead
15904                        // give them the best state after that.
15905                        clientProcState =
15906                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15907                    }
15908                }
15909                if (procState > clientProcState) {
15910                    procState = clientProcState;
15911                }
15912                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15913                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15914                }
15915            }
15916            // If the provider has external (non-framework) process
15917            // dependencies, ensure that its adjustment is at least
15918            // FOREGROUND_APP_ADJ.
15919            if (cpr.hasExternalProcessHandles()) {
15920                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15921                    adj = ProcessList.FOREGROUND_APP_ADJ;
15922                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15923                    app.cached = false;
15924                    app.adjType = "provider";
15925                    app.adjTarget = cpr.name;
15926                }
15927                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15928                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15929                }
15930            }
15931        }
15932
15933        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15934            // A client of one of our services or providers is in the top state.  We
15935            // *may* want to be in the top state, but not if we are already running in
15936            // the background for some other reason.  For the decision here, we are going
15937            // to pick out a few specific states that we want to remain in when a client
15938            // is top (states that tend to be longer-term) and otherwise allow it to go
15939            // to the top state.
15940            switch (procState) {
15941                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15942                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15943                case ActivityManager.PROCESS_STATE_SERVICE:
15944                    // These all are longer-term states, so pull them up to the top
15945                    // of the background states, but not all the way to the top state.
15946                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15947                    break;
15948                default:
15949                    // Otherwise, top is a better choice, so take it.
15950                    procState = ActivityManager.PROCESS_STATE_TOP;
15951                    break;
15952            }
15953        }
15954
15955        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15956            if (app.hasClientActivities) {
15957                // This is a cached process, but with client activities.  Mark it so.
15958                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15959                app.adjType = "cch-client-act";
15960            } else if (app.treatLikeActivity) {
15961                // This is a cached process, but somebody wants us to treat it like it has
15962                // an activity, okay!
15963                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15964                app.adjType = "cch-as-act";
15965            }
15966        }
15967
15968        if (adj == ProcessList.SERVICE_ADJ) {
15969            if (doingAll) {
15970                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15971                mNewNumServiceProcs++;
15972                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15973                if (!app.serviceb) {
15974                    // This service isn't far enough down on the LRU list to
15975                    // normally be a B service, but if we are low on RAM and it
15976                    // is large we want to force it down since we would prefer to
15977                    // keep launcher over it.
15978                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15979                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15980                        app.serviceHighRam = true;
15981                        app.serviceb = true;
15982                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15983                    } else {
15984                        mNewNumAServiceProcs++;
15985                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15986                    }
15987                } else {
15988                    app.serviceHighRam = false;
15989                }
15990            }
15991            if (app.serviceb) {
15992                adj = ProcessList.SERVICE_B_ADJ;
15993            }
15994        }
15995
15996        app.curRawAdj = adj;
15997
15998        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15999        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16000        if (adj > app.maxAdj) {
16001            adj = app.maxAdj;
16002            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16003                schedGroup = Process.THREAD_GROUP_DEFAULT;
16004            }
16005        }
16006
16007        // Do final modification to adj.  Everything we do between here and applying
16008        // the final setAdj must be done in this function, because we will also use
16009        // it when computing the final cached adj later.  Note that we don't need to
16010        // worry about this for max adj above, since max adj will always be used to
16011        // keep it out of the cached vaues.
16012        app.curAdj = app.modifyRawOomAdj(adj);
16013        app.curSchedGroup = schedGroup;
16014        app.curProcState = procState;
16015        app.foregroundActivities = foregroundActivities;
16016
16017        return app.curRawAdj;
16018    }
16019
16020    /**
16021     * Schedule PSS collection of a process.
16022     */
16023    void requestPssLocked(ProcessRecord proc, int procState) {
16024        if (mPendingPssProcesses.contains(proc)) {
16025            return;
16026        }
16027        if (mPendingPssProcesses.size() == 0) {
16028            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16029        }
16030        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16031        proc.pssProcState = procState;
16032        mPendingPssProcesses.add(proc);
16033    }
16034
16035    /**
16036     * Schedule PSS collection of all processes.
16037     */
16038    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16039        if (!always) {
16040            if (now < (mLastFullPssTime +
16041                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16042                return;
16043            }
16044        }
16045        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16046        mLastFullPssTime = now;
16047        mFullPssPending = true;
16048        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16049        mPendingPssProcesses.clear();
16050        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16051            ProcessRecord app = mLruProcesses.get(i);
16052            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16053                app.pssProcState = app.setProcState;
16054                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16055                        isSleeping(), now);
16056                mPendingPssProcesses.add(app);
16057            }
16058        }
16059        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16060    }
16061
16062    /**
16063     * Ask a given process to GC right now.
16064     */
16065    final void performAppGcLocked(ProcessRecord app) {
16066        try {
16067            app.lastRequestedGc = SystemClock.uptimeMillis();
16068            if (app.thread != null) {
16069                if (app.reportLowMemory) {
16070                    app.reportLowMemory = false;
16071                    app.thread.scheduleLowMemory();
16072                } else {
16073                    app.thread.processInBackground();
16074                }
16075            }
16076        } catch (Exception e) {
16077            // whatever.
16078        }
16079    }
16080
16081    /**
16082     * Returns true if things are idle enough to perform GCs.
16083     */
16084    private final boolean canGcNowLocked() {
16085        boolean processingBroadcasts = false;
16086        for (BroadcastQueue q : mBroadcastQueues) {
16087            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16088                processingBroadcasts = true;
16089            }
16090        }
16091        return !processingBroadcasts
16092                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16093    }
16094
16095    /**
16096     * Perform GCs on all processes that are waiting for it, but only
16097     * if things are idle.
16098     */
16099    final void performAppGcsLocked() {
16100        final int N = mProcessesToGc.size();
16101        if (N <= 0) {
16102            return;
16103        }
16104        if (canGcNowLocked()) {
16105            while (mProcessesToGc.size() > 0) {
16106                ProcessRecord proc = mProcessesToGc.remove(0);
16107                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16108                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16109                            <= SystemClock.uptimeMillis()) {
16110                        // To avoid spamming the system, we will GC processes one
16111                        // at a time, waiting a few seconds between each.
16112                        performAppGcLocked(proc);
16113                        scheduleAppGcsLocked();
16114                        return;
16115                    } else {
16116                        // It hasn't been long enough since we last GCed this
16117                        // process...  put it in the list to wait for its time.
16118                        addProcessToGcListLocked(proc);
16119                        break;
16120                    }
16121                }
16122            }
16123
16124            scheduleAppGcsLocked();
16125        }
16126    }
16127
16128    /**
16129     * If all looks good, perform GCs on all processes waiting for them.
16130     */
16131    final void performAppGcsIfAppropriateLocked() {
16132        if (canGcNowLocked()) {
16133            performAppGcsLocked();
16134            return;
16135        }
16136        // Still not idle, wait some more.
16137        scheduleAppGcsLocked();
16138    }
16139
16140    /**
16141     * Schedule the execution of all pending app GCs.
16142     */
16143    final void scheduleAppGcsLocked() {
16144        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16145
16146        if (mProcessesToGc.size() > 0) {
16147            // Schedule a GC for the time to the next process.
16148            ProcessRecord proc = mProcessesToGc.get(0);
16149            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16150
16151            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16152            long now = SystemClock.uptimeMillis();
16153            if (when < (now+GC_TIMEOUT)) {
16154                when = now + GC_TIMEOUT;
16155            }
16156            mHandler.sendMessageAtTime(msg, when);
16157        }
16158    }
16159
16160    /**
16161     * Add a process to the array of processes waiting to be GCed.  Keeps the
16162     * list in sorted order by the last GC time.  The process can't already be
16163     * on the list.
16164     */
16165    final void addProcessToGcListLocked(ProcessRecord proc) {
16166        boolean added = false;
16167        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16168            if (mProcessesToGc.get(i).lastRequestedGc <
16169                    proc.lastRequestedGc) {
16170                added = true;
16171                mProcessesToGc.add(i+1, proc);
16172                break;
16173            }
16174        }
16175        if (!added) {
16176            mProcessesToGc.add(0, proc);
16177        }
16178    }
16179
16180    /**
16181     * Set up to ask a process to GC itself.  This will either do it
16182     * immediately, or put it on the list of processes to gc the next
16183     * time things are idle.
16184     */
16185    final void scheduleAppGcLocked(ProcessRecord app) {
16186        long now = SystemClock.uptimeMillis();
16187        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16188            return;
16189        }
16190        if (!mProcessesToGc.contains(app)) {
16191            addProcessToGcListLocked(app);
16192            scheduleAppGcsLocked();
16193        }
16194    }
16195
16196    final void checkExcessivePowerUsageLocked(boolean doKills) {
16197        updateCpuStatsNow();
16198
16199        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16200        boolean doWakeKills = doKills;
16201        boolean doCpuKills = doKills;
16202        if (mLastPowerCheckRealtime == 0) {
16203            doWakeKills = false;
16204        }
16205        if (mLastPowerCheckUptime == 0) {
16206            doCpuKills = false;
16207        }
16208        if (stats.isScreenOn()) {
16209            doWakeKills = false;
16210        }
16211        final long curRealtime = SystemClock.elapsedRealtime();
16212        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16213        final long curUptime = SystemClock.uptimeMillis();
16214        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16215        mLastPowerCheckRealtime = curRealtime;
16216        mLastPowerCheckUptime = curUptime;
16217        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16218            doWakeKills = false;
16219        }
16220        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16221            doCpuKills = false;
16222        }
16223        int i = mLruProcesses.size();
16224        while (i > 0) {
16225            i--;
16226            ProcessRecord app = mLruProcesses.get(i);
16227            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16228                long wtime;
16229                synchronized (stats) {
16230                    wtime = stats.getProcessWakeTime(app.info.uid,
16231                            app.pid, curRealtime);
16232                }
16233                long wtimeUsed = wtime - app.lastWakeTime;
16234                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16235                if (DEBUG_POWER) {
16236                    StringBuilder sb = new StringBuilder(128);
16237                    sb.append("Wake for ");
16238                    app.toShortString(sb);
16239                    sb.append(": over ");
16240                    TimeUtils.formatDuration(realtimeSince, sb);
16241                    sb.append(" used ");
16242                    TimeUtils.formatDuration(wtimeUsed, sb);
16243                    sb.append(" (");
16244                    sb.append((wtimeUsed*100)/realtimeSince);
16245                    sb.append("%)");
16246                    Slog.i(TAG, sb.toString());
16247                    sb.setLength(0);
16248                    sb.append("CPU for ");
16249                    app.toShortString(sb);
16250                    sb.append(": over ");
16251                    TimeUtils.formatDuration(uptimeSince, sb);
16252                    sb.append(" used ");
16253                    TimeUtils.formatDuration(cputimeUsed, sb);
16254                    sb.append(" (");
16255                    sb.append((cputimeUsed*100)/uptimeSince);
16256                    sb.append("%)");
16257                    Slog.i(TAG, sb.toString());
16258                }
16259                // If a process has held a wake lock for more
16260                // than 50% of the time during this period,
16261                // that sounds bad.  Kill!
16262                if (doWakeKills && realtimeSince > 0
16263                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16264                    synchronized (stats) {
16265                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16266                                realtimeSince, wtimeUsed);
16267                    }
16268                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16269                            + " during " + realtimeSince);
16270                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16271                } else if (doCpuKills && uptimeSince > 0
16272                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16273                    synchronized (stats) {
16274                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16275                                uptimeSince, cputimeUsed);
16276                    }
16277                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16278                            + " during " + uptimeSince);
16279                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16280                } else {
16281                    app.lastWakeTime = wtime;
16282                    app.lastCpuTime = app.curCpuTime;
16283                }
16284            }
16285        }
16286    }
16287
16288    private final boolean applyOomAdjLocked(ProcessRecord app,
16289            ProcessRecord TOP_APP, boolean doingAll, long now) {
16290        boolean success = true;
16291
16292        if (app.curRawAdj != app.setRawAdj) {
16293            app.setRawAdj = app.curRawAdj;
16294        }
16295
16296        int changes = 0;
16297
16298        if (app.curAdj != app.setAdj) {
16299            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16300            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16301                TAG, "Set " + app.pid + " " + app.processName +
16302                " adj " + app.curAdj + ": " + app.adjType);
16303            app.setAdj = app.curAdj;
16304        }
16305
16306        if (app.setSchedGroup != app.curSchedGroup) {
16307            app.setSchedGroup = app.curSchedGroup;
16308            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16309                    "Setting process group of " + app.processName
16310                    + " to " + app.curSchedGroup);
16311            if (app.waitingToKill != null &&
16312                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16313                killUnneededProcessLocked(app, app.waitingToKill);
16314                success = false;
16315            } else {
16316                if (true) {
16317                    long oldId = Binder.clearCallingIdentity();
16318                    try {
16319                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16320                    } catch (Exception e) {
16321                        Slog.w(TAG, "Failed setting process group of " + app.pid
16322                                + " to " + app.curSchedGroup);
16323                        e.printStackTrace();
16324                    } finally {
16325                        Binder.restoreCallingIdentity(oldId);
16326                    }
16327                } else {
16328                    if (app.thread != null) {
16329                        try {
16330                            app.thread.setSchedulingGroup(app.curSchedGroup);
16331                        } catch (RemoteException e) {
16332                        }
16333                    }
16334                }
16335                Process.setSwappiness(app.pid,
16336                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16337            }
16338        }
16339        if (app.repForegroundActivities != app.foregroundActivities) {
16340            app.repForegroundActivities = app.foregroundActivities;
16341            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16342        }
16343        if (app.repProcState != app.curProcState) {
16344            app.repProcState = app.curProcState;
16345            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16346            if (app.thread != null) {
16347                try {
16348                    if (false) {
16349                        //RuntimeException h = new RuntimeException("here");
16350                        Slog.i(TAG, "Sending new process state " + app.repProcState
16351                                + " to " + app /*, h*/);
16352                    }
16353                    app.thread.setProcessState(app.repProcState);
16354                } catch (RemoteException e) {
16355                }
16356            }
16357        }
16358        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16359                app.setProcState)) {
16360            app.lastStateTime = now;
16361            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16362                    isSleeping(), now);
16363            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16364                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16365                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16366                    + (app.nextPssTime-now) + ": " + app);
16367        } else {
16368            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16369                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16370                requestPssLocked(app, app.setProcState);
16371                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16372                        isSleeping(), now);
16373            } else if (false && DEBUG_PSS) {
16374                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16375            }
16376        }
16377        if (app.setProcState != app.curProcState) {
16378            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16379                    "Proc state change of " + app.processName
16380                    + " to " + app.curProcState);
16381            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16382            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16383            if (setImportant && !curImportant) {
16384                // This app is no longer something we consider important enough to allow to
16385                // use arbitrary amounts of battery power.  Note
16386                // its current wake lock time to later know to kill it if
16387                // it is not behaving well.
16388                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16389                synchronized (stats) {
16390                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16391                            app.pid, SystemClock.elapsedRealtime());
16392                }
16393                app.lastCpuTime = app.curCpuTime;
16394
16395            }
16396            app.setProcState = app.curProcState;
16397            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16398                app.notCachedSinceIdle = false;
16399            }
16400            if (!doingAll) {
16401                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16402            } else {
16403                app.procStateChanged = true;
16404            }
16405        }
16406
16407        if (changes != 0) {
16408            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16409            int i = mPendingProcessChanges.size()-1;
16410            ProcessChangeItem item = null;
16411            while (i >= 0) {
16412                item = mPendingProcessChanges.get(i);
16413                if (item.pid == app.pid) {
16414                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16415                    break;
16416                }
16417                i--;
16418            }
16419            if (i < 0) {
16420                // No existing item in pending changes; need a new one.
16421                final int NA = mAvailProcessChanges.size();
16422                if (NA > 0) {
16423                    item = mAvailProcessChanges.remove(NA-1);
16424                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16425                } else {
16426                    item = new ProcessChangeItem();
16427                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16428                }
16429                item.changes = 0;
16430                item.pid = app.pid;
16431                item.uid = app.info.uid;
16432                if (mPendingProcessChanges.size() == 0) {
16433                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16434                            "*** Enqueueing dispatch processes changed!");
16435                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16436                }
16437                mPendingProcessChanges.add(item);
16438            }
16439            item.changes |= changes;
16440            item.processState = app.repProcState;
16441            item.foregroundActivities = app.repForegroundActivities;
16442            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16443                    + Integer.toHexString(System.identityHashCode(item))
16444                    + " " + app.toShortString() + ": changes=" + item.changes
16445                    + " procState=" + item.processState
16446                    + " foreground=" + item.foregroundActivities
16447                    + " type=" + app.adjType + " source=" + app.adjSource
16448                    + " target=" + app.adjTarget);
16449        }
16450
16451        return success;
16452    }
16453
16454    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16455        if (proc.thread != null) {
16456            if (proc.baseProcessTracker != null) {
16457                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16458            }
16459            if (proc.repProcState >= 0) {
16460                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16461                        proc.repProcState);
16462            }
16463        }
16464    }
16465
16466    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16467            ProcessRecord TOP_APP, boolean doingAll, long now) {
16468        if (app.thread == null) {
16469            return false;
16470        }
16471
16472        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16473
16474        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16475    }
16476
16477    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16478            boolean oomAdj) {
16479        if (isForeground != proc.foregroundServices) {
16480            proc.foregroundServices = isForeground;
16481            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16482                    proc.info.uid);
16483            if (isForeground) {
16484                if (curProcs == null) {
16485                    curProcs = new ArrayList<ProcessRecord>();
16486                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16487                }
16488                if (!curProcs.contains(proc)) {
16489                    curProcs.add(proc);
16490                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16491                            proc.info.packageName, proc.info.uid);
16492                }
16493            } else {
16494                if (curProcs != null) {
16495                    if (curProcs.remove(proc)) {
16496                        mBatteryStatsService.noteEvent(
16497                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16498                                proc.info.packageName, proc.info.uid);
16499                        if (curProcs.size() <= 0) {
16500                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16501                        }
16502                    }
16503                }
16504            }
16505            if (oomAdj) {
16506                updateOomAdjLocked();
16507            }
16508        }
16509    }
16510
16511    private final ActivityRecord resumedAppLocked() {
16512        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16513        String pkg;
16514        int uid;
16515        if (act != null) {
16516            pkg = act.packageName;
16517            uid = act.info.applicationInfo.uid;
16518        } else {
16519            pkg = null;
16520            uid = -1;
16521        }
16522        // Has the UID or resumed package name changed?
16523        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16524                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16525            if (mCurResumedPackage != null) {
16526                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16527                        mCurResumedPackage, mCurResumedUid);
16528            }
16529            mCurResumedPackage = pkg;
16530            mCurResumedUid = uid;
16531            if (mCurResumedPackage != null) {
16532                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16533                        mCurResumedPackage, mCurResumedUid);
16534            }
16535        }
16536        return act;
16537    }
16538
16539    final boolean updateOomAdjLocked(ProcessRecord app) {
16540        final ActivityRecord TOP_ACT = resumedAppLocked();
16541        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16542        final boolean wasCached = app.cached;
16543
16544        mAdjSeq++;
16545
16546        // This is the desired cached adjusment we want to tell it to use.
16547        // If our app is currently cached, we know it, and that is it.  Otherwise,
16548        // we don't know it yet, and it needs to now be cached we will then
16549        // need to do a complete oom adj.
16550        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16551                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16552        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16553                SystemClock.uptimeMillis());
16554        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16555            // Changed to/from cached state, so apps after it in the LRU
16556            // list may also be changed.
16557            updateOomAdjLocked();
16558        }
16559        return success;
16560    }
16561
16562    final void updateOomAdjLocked() {
16563        final ActivityRecord TOP_ACT = resumedAppLocked();
16564        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16565        final long now = SystemClock.uptimeMillis();
16566        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16567        final int N = mLruProcesses.size();
16568
16569        if (false) {
16570            RuntimeException e = new RuntimeException();
16571            e.fillInStackTrace();
16572            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16573        }
16574
16575        mAdjSeq++;
16576        mNewNumServiceProcs = 0;
16577        mNewNumAServiceProcs = 0;
16578
16579        final int emptyProcessLimit;
16580        final int cachedProcessLimit;
16581        if (mProcessLimit <= 0) {
16582            emptyProcessLimit = cachedProcessLimit = 0;
16583        } else if (mProcessLimit == 1) {
16584            emptyProcessLimit = 1;
16585            cachedProcessLimit = 0;
16586        } else {
16587            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16588            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16589        }
16590
16591        // Let's determine how many processes we have running vs.
16592        // how many slots we have for background processes; we may want
16593        // to put multiple processes in a slot of there are enough of
16594        // them.
16595        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16596                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16597        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16598        if (numEmptyProcs > cachedProcessLimit) {
16599            // If there are more empty processes than our limit on cached
16600            // processes, then use the cached process limit for the factor.
16601            // This ensures that the really old empty processes get pushed
16602            // down to the bottom, so if we are running low on memory we will
16603            // have a better chance at keeping around more cached processes
16604            // instead of a gazillion empty processes.
16605            numEmptyProcs = cachedProcessLimit;
16606        }
16607        int emptyFactor = numEmptyProcs/numSlots;
16608        if (emptyFactor < 1) emptyFactor = 1;
16609        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16610        if (cachedFactor < 1) cachedFactor = 1;
16611        int stepCached = 0;
16612        int stepEmpty = 0;
16613        int numCached = 0;
16614        int numEmpty = 0;
16615        int numTrimming = 0;
16616
16617        mNumNonCachedProcs = 0;
16618        mNumCachedHiddenProcs = 0;
16619
16620        // First update the OOM adjustment for each of the
16621        // application processes based on their current state.
16622        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16623        int nextCachedAdj = curCachedAdj+1;
16624        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16625        int nextEmptyAdj = curEmptyAdj+2;
16626        for (int i=N-1; i>=0; i--) {
16627            ProcessRecord app = mLruProcesses.get(i);
16628            if (!app.killedByAm && app.thread != null) {
16629                app.procStateChanged = false;
16630                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16631
16632                // If we haven't yet assigned the final cached adj
16633                // to the process, do that now.
16634                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16635                    switch (app.curProcState) {
16636                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16637                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16638                            // This process is a cached process holding activities...
16639                            // assign it the next cached value for that type, and then
16640                            // step that cached level.
16641                            app.curRawAdj = curCachedAdj;
16642                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16643                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16644                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16645                                    + ")");
16646                            if (curCachedAdj != nextCachedAdj) {
16647                                stepCached++;
16648                                if (stepCached >= cachedFactor) {
16649                                    stepCached = 0;
16650                                    curCachedAdj = nextCachedAdj;
16651                                    nextCachedAdj += 2;
16652                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16653                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16654                                    }
16655                                }
16656                            }
16657                            break;
16658                        default:
16659                            // For everything else, assign next empty cached process
16660                            // level and bump that up.  Note that this means that
16661                            // long-running services that have dropped down to the
16662                            // cached level will be treated as empty (since their process
16663                            // state is still as a service), which is what we want.
16664                            app.curRawAdj = curEmptyAdj;
16665                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16666                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16667                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16668                                    + ")");
16669                            if (curEmptyAdj != nextEmptyAdj) {
16670                                stepEmpty++;
16671                                if (stepEmpty >= emptyFactor) {
16672                                    stepEmpty = 0;
16673                                    curEmptyAdj = nextEmptyAdj;
16674                                    nextEmptyAdj += 2;
16675                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16676                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16677                                    }
16678                                }
16679                            }
16680                            break;
16681                    }
16682                }
16683
16684                applyOomAdjLocked(app, TOP_APP, true, now);
16685
16686                // Count the number of process types.
16687                switch (app.curProcState) {
16688                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16689                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16690                        mNumCachedHiddenProcs++;
16691                        numCached++;
16692                        if (numCached > cachedProcessLimit) {
16693                            killUnneededProcessLocked(app, "cached #" + numCached);
16694                        }
16695                        break;
16696                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16697                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16698                                && app.lastActivityTime < oldTime) {
16699                            killUnneededProcessLocked(app, "empty for "
16700                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16701                                    / 1000) + "s");
16702                        } else {
16703                            numEmpty++;
16704                            if (numEmpty > emptyProcessLimit) {
16705                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16706                            }
16707                        }
16708                        break;
16709                    default:
16710                        mNumNonCachedProcs++;
16711                        break;
16712                }
16713
16714                if (app.isolated && app.services.size() <= 0) {
16715                    // If this is an isolated process, and there are no
16716                    // services running in it, then the process is no longer
16717                    // needed.  We agressively kill these because we can by
16718                    // definition not re-use the same process again, and it is
16719                    // good to avoid having whatever code was running in them
16720                    // left sitting around after no longer needed.
16721                    killUnneededProcessLocked(app, "isolated not needed");
16722                }
16723
16724                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16725                        && !app.killedByAm) {
16726                    numTrimming++;
16727                }
16728            }
16729        }
16730
16731        mNumServiceProcs = mNewNumServiceProcs;
16732
16733        // Now determine the memory trimming level of background processes.
16734        // Unfortunately we need to start at the back of the list to do this
16735        // properly.  We only do this if the number of background apps we
16736        // are managing to keep around is less than half the maximum we desire;
16737        // if we are keeping a good number around, we'll let them use whatever
16738        // memory they want.
16739        final int numCachedAndEmpty = numCached + numEmpty;
16740        int memFactor;
16741        if (numCached <= ProcessList.TRIM_CACHED_APPS
16742                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16743            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16744                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16745            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16746                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16747            } else {
16748                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16749            }
16750        } else {
16751            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16752        }
16753        // We always allow the memory level to go up (better).  We only allow it to go
16754        // down if we are in a state where that is allowed, *and* the total number of processes
16755        // has gone down since last time.
16756        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16757                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16758                + " last=" + mLastNumProcesses);
16759        if (memFactor > mLastMemoryLevel) {
16760            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16761                memFactor = mLastMemoryLevel;
16762                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16763            }
16764        }
16765        mLastMemoryLevel = memFactor;
16766        mLastNumProcesses = mLruProcesses.size();
16767        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16768        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16769        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16770            if (mLowRamStartTime == 0) {
16771                mLowRamStartTime = now;
16772            }
16773            int step = 0;
16774            int fgTrimLevel;
16775            switch (memFactor) {
16776                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16777                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16778                    break;
16779                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16780                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16781                    break;
16782                default:
16783                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16784                    break;
16785            }
16786            int factor = numTrimming/3;
16787            int minFactor = 2;
16788            if (mHomeProcess != null) minFactor++;
16789            if (mPreviousProcess != null) minFactor++;
16790            if (factor < minFactor) factor = minFactor;
16791            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16792            for (int i=N-1; i>=0; i--) {
16793                ProcessRecord app = mLruProcesses.get(i);
16794                if (allChanged || app.procStateChanged) {
16795                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16796                    app.procStateChanged = false;
16797                }
16798                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16799                        && !app.killedByAm) {
16800                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16801                        try {
16802                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16803                                    "Trimming memory of " + app.processName
16804                                    + " to " + curLevel);
16805                            app.thread.scheduleTrimMemory(curLevel);
16806                        } catch (RemoteException e) {
16807                        }
16808                        if (false) {
16809                            // For now we won't do this; our memory trimming seems
16810                            // to be good enough at this point that destroying
16811                            // activities causes more harm than good.
16812                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16813                                    && app != mHomeProcess && app != mPreviousProcess) {
16814                                // Need to do this on its own message because the stack may not
16815                                // be in a consistent state at this point.
16816                                // For these apps we will also finish their activities
16817                                // to help them free memory.
16818                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16819                            }
16820                        }
16821                    }
16822                    app.trimMemoryLevel = curLevel;
16823                    step++;
16824                    if (step >= factor) {
16825                        step = 0;
16826                        switch (curLevel) {
16827                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16828                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16829                                break;
16830                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16831                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16832                                break;
16833                        }
16834                    }
16835                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16836                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16837                            && app.thread != null) {
16838                        try {
16839                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16840                                    "Trimming memory of heavy-weight " + app.processName
16841                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16842                            app.thread.scheduleTrimMemory(
16843                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16844                        } catch (RemoteException e) {
16845                        }
16846                    }
16847                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16848                } else {
16849                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16850                            || app.systemNoUi) && app.pendingUiClean) {
16851                        // If this application is now in the background and it
16852                        // had done UI, then give it the special trim level to
16853                        // have it free UI resources.
16854                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16855                        if (app.trimMemoryLevel < level && app.thread != null) {
16856                            try {
16857                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16858                                        "Trimming memory of bg-ui " + app.processName
16859                                        + " to " + level);
16860                                app.thread.scheduleTrimMemory(level);
16861                            } catch (RemoteException e) {
16862                            }
16863                        }
16864                        app.pendingUiClean = false;
16865                    }
16866                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16867                        try {
16868                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16869                                    "Trimming memory of fg " + app.processName
16870                                    + " to " + fgTrimLevel);
16871                            app.thread.scheduleTrimMemory(fgTrimLevel);
16872                        } catch (RemoteException e) {
16873                        }
16874                    }
16875                    app.trimMemoryLevel = fgTrimLevel;
16876                }
16877            }
16878        } else {
16879            if (mLowRamStartTime != 0) {
16880                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16881                mLowRamStartTime = 0;
16882            }
16883            for (int i=N-1; i>=0; i--) {
16884                ProcessRecord app = mLruProcesses.get(i);
16885                if (allChanged || app.procStateChanged) {
16886                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16887                    app.procStateChanged = false;
16888                }
16889                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16890                        || app.systemNoUi) && app.pendingUiClean) {
16891                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16892                            && app.thread != null) {
16893                        try {
16894                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16895                                    "Trimming memory of ui hidden " + app.processName
16896                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16897                            app.thread.scheduleTrimMemory(
16898                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16899                        } catch (RemoteException e) {
16900                        }
16901                    }
16902                    app.pendingUiClean = false;
16903                }
16904                app.trimMemoryLevel = 0;
16905            }
16906        }
16907
16908        if (mAlwaysFinishActivities) {
16909            // Need to do this on its own message because the stack may not
16910            // be in a consistent state at this point.
16911            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16912        }
16913
16914        if (allChanged) {
16915            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16916        }
16917
16918        if (mProcessStats.shouldWriteNowLocked(now)) {
16919            mHandler.post(new Runnable() {
16920                @Override public void run() {
16921                    synchronized (ActivityManagerService.this) {
16922                        mProcessStats.writeStateAsyncLocked();
16923                    }
16924                }
16925            });
16926        }
16927
16928        if (DEBUG_OOM_ADJ) {
16929            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16930        }
16931    }
16932
16933    final void trimApplications() {
16934        synchronized (this) {
16935            int i;
16936
16937            // First remove any unused application processes whose package
16938            // has been removed.
16939            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16940                final ProcessRecord app = mRemovedProcesses.get(i);
16941                if (app.activities.size() == 0
16942                        && app.curReceiver == null && app.services.size() == 0) {
16943                    Slog.i(
16944                        TAG, "Exiting empty application process "
16945                        + app.processName + " ("
16946                        + (app.thread != null ? app.thread.asBinder() : null)
16947                        + ")\n");
16948                    if (app.pid > 0 && app.pid != MY_PID) {
16949                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16950                                app.processName, app.setAdj, "empty");
16951                        app.killedByAm = true;
16952                        Process.killProcessQuiet(app.pid);
16953                        Process.killProcessGroup(app.info.uid, app.pid);
16954                    } else {
16955                        try {
16956                            app.thread.scheduleExit();
16957                        } catch (Exception e) {
16958                            // Ignore exceptions.
16959                        }
16960                    }
16961                    cleanUpApplicationRecordLocked(app, false, true, -1);
16962                    mRemovedProcesses.remove(i);
16963
16964                    if (app.persistent) {
16965                        addAppLocked(app.info, false, null /* ABI override */);
16966                    }
16967                }
16968            }
16969
16970            // Now update the oom adj for all processes.
16971            updateOomAdjLocked();
16972        }
16973    }
16974
16975    /** This method sends the specified signal to each of the persistent apps */
16976    public void signalPersistentProcesses(int sig) throws RemoteException {
16977        if (sig != Process.SIGNAL_USR1) {
16978            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16979        }
16980
16981        synchronized (this) {
16982            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16983                    != PackageManager.PERMISSION_GRANTED) {
16984                throw new SecurityException("Requires permission "
16985                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16986            }
16987
16988            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16989                ProcessRecord r = mLruProcesses.get(i);
16990                if (r.thread != null && r.persistent) {
16991                    Process.sendSignal(r.pid, sig);
16992                }
16993            }
16994        }
16995    }
16996
16997    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16998        if (proc == null || proc == mProfileProc) {
16999            proc = mProfileProc;
17000            path = mProfileFile;
17001            profileType = mProfileType;
17002            clearProfilerLocked();
17003        }
17004        if (proc == null) {
17005            return;
17006        }
17007        try {
17008            proc.thread.profilerControl(false, path, null, profileType);
17009        } catch (RemoteException e) {
17010            throw new IllegalStateException("Process disappeared");
17011        }
17012    }
17013
17014    private void clearProfilerLocked() {
17015        if (mProfileFd != null) {
17016            try {
17017                mProfileFd.close();
17018            } catch (IOException e) {
17019            }
17020        }
17021        mProfileApp = null;
17022        mProfileProc = null;
17023        mProfileFile = null;
17024        mProfileType = 0;
17025        mAutoStopProfiler = false;
17026    }
17027
17028    public boolean profileControl(String process, int userId, boolean start,
17029            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17030
17031        try {
17032            synchronized (this) {
17033                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17034                // its own permission.
17035                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17036                        != PackageManager.PERMISSION_GRANTED) {
17037                    throw new SecurityException("Requires permission "
17038                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17039                }
17040
17041                if (start && fd == null) {
17042                    throw new IllegalArgumentException("null fd");
17043                }
17044
17045                ProcessRecord proc = null;
17046                if (process != null) {
17047                    proc = findProcessLocked(process, userId, "profileControl");
17048                }
17049
17050                if (start && (proc == null || proc.thread == null)) {
17051                    throw new IllegalArgumentException("Unknown process: " + process);
17052                }
17053
17054                if (start) {
17055                    stopProfilerLocked(null, null, 0);
17056                    setProfileApp(proc.info, proc.processName, path, fd, false);
17057                    mProfileProc = proc;
17058                    mProfileType = profileType;
17059                    try {
17060                        fd = fd.dup();
17061                    } catch (IOException e) {
17062                        fd = null;
17063                    }
17064                    proc.thread.profilerControl(start, path, fd, profileType);
17065                    fd = null;
17066                    mProfileFd = null;
17067                } else {
17068                    stopProfilerLocked(proc, path, profileType);
17069                    if (fd != null) {
17070                        try {
17071                            fd.close();
17072                        } catch (IOException e) {
17073                        }
17074                    }
17075                }
17076
17077                return true;
17078            }
17079        } catch (RemoteException e) {
17080            throw new IllegalStateException("Process disappeared");
17081        } finally {
17082            if (fd != null) {
17083                try {
17084                    fd.close();
17085                } catch (IOException e) {
17086                }
17087            }
17088        }
17089    }
17090
17091    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17092        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17093                userId, true, ALLOW_FULL_ONLY, callName, null);
17094        ProcessRecord proc = null;
17095        try {
17096            int pid = Integer.parseInt(process);
17097            synchronized (mPidsSelfLocked) {
17098                proc = mPidsSelfLocked.get(pid);
17099            }
17100        } catch (NumberFormatException e) {
17101        }
17102
17103        if (proc == null) {
17104            ArrayMap<String, SparseArray<ProcessRecord>> all
17105                    = mProcessNames.getMap();
17106            SparseArray<ProcessRecord> procs = all.get(process);
17107            if (procs != null && procs.size() > 0) {
17108                proc = procs.valueAt(0);
17109                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17110                    for (int i=1; i<procs.size(); i++) {
17111                        ProcessRecord thisProc = procs.valueAt(i);
17112                        if (thisProc.userId == userId) {
17113                            proc = thisProc;
17114                            break;
17115                        }
17116                    }
17117                }
17118            }
17119        }
17120
17121        return proc;
17122    }
17123
17124    public boolean dumpHeap(String process, int userId, boolean managed,
17125            String path, ParcelFileDescriptor fd) throws RemoteException {
17126
17127        try {
17128            synchronized (this) {
17129                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17130                // its own permission (same as profileControl).
17131                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17132                        != PackageManager.PERMISSION_GRANTED) {
17133                    throw new SecurityException("Requires permission "
17134                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17135                }
17136
17137                if (fd == null) {
17138                    throw new IllegalArgumentException("null fd");
17139                }
17140
17141                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17142                if (proc == null || proc.thread == null) {
17143                    throw new IllegalArgumentException("Unknown process: " + process);
17144                }
17145
17146                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17147                if (!isDebuggable) {
17148                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17149                        throw new SecurityException("Process not debuggable: " + proc);
17150                    }
17151                }
17152
17153                proc.thread.dumpHeap(managed, path, fd);
17154                fd = null;
17155                return true;
17156            }
17157        } catch (RemoteException e) {
17158            throw new IllegalStateException("Process disappeared");
17159        } finally {
17160            if (fd != null) {
17161                try {
17162                    fd.close();
17163                } catch (IOException e) {
17164                }
17165            }
17166        }
17167    }
17168
17169    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17170    public void monitor() {
17171        synchronized (this) { }
17172    }
17173
17174    void onCoreSettingsChange(Bundle settings) {
17175        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17176            ProcessRecord processRecord = mLruProcesses.get(i);
17177            try {
17178                if (processRecord.thread != null) {
17179                    processRecord.thread.setCoreSettings(settings);
17180                }
17181            } catch (RemoteException re) {
17182                /* ignore */
17183            }
17184        }
17185    }
17186
17187    // Multi-user methods
17188
17189    /**
17190     * Start user, if its not already running, but don't bring it to foreground.
17191     */
17192    @Override
17193    public boolean startUserInBackground(final int userId) {
17194        return startUser(userId, /* foreground */ false);
17195    }
17196
17197    /**
17198     * Refreshes the list of users related to the current user when either a
17199     * user switch happens or when a new related user is started in the
17200     * background.
17201     */
17202    private void updateCurrentProfileIdsLocked() {
17203        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17204                mCurrentUserId, false /* enabledOnly */);
17205        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17206        for (int i = 0; i < currentProfileIds.length; i++) {
17207            currentProfileIds[i] = profiles.get(i).id;
17208        }
17209        mCurrentProfileIds = currentProfileIds;
17210
17211        synchronized (mUserProfileGroupIdsSelfLocked) {
17212            mUserProfileGroupIdsSelfLocked.clear();
17213            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17214            for (int i = 0; i < users.size(); i++) {
17215                UserInfo user = users.get(i);
17216                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17217                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17218                }
17219            }
17220        }
17221    }
17222
17223    private Set getProfileIdsLocked(int userId) {
17224        Set userIds = new HashSet<Integer>();
17225        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17226                userId, false /* enabledOnly */);
17227        for (UserInfo user : profiles) {
17228            userIds.add(Integer.valueOf(user.id));
17229        }
17230        return userIds;
17231    }
17232
17233    @Override
17234    public boolean switchUser(final int userId) {
17235        return startUser(userId, /* foregound */ true);
17236    }
17237
17238    private boolean startUser(final int userId, boolean foreground) {
17239        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17240                != PackageManager.PERMISSION_GRANTED) {
17241            String msg = "Permission Denial: switchUser() from pid="
17242                    + Binder.getCallingPid()
17243                    + ", uid=" + Binder.getCallingUid()
17244                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17245            Slog.w(TAG, msg);
17246            throw new SecurityException(msg);
17247        }
17248
17249        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17250
17251        final long ident = Binder.clearCallingIdentity();
17252        try {
17253            synchronized (this) {
17254                final int oldUserId = mCurrentUserId;
17255                if (oldUserId == userId) {
17256                    return true;
17257                }
17258
17259                mStackSupervisor.setLockTaskModeLocked(null, false);
17260
17261                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17262                if (userInfo == null) {
17263                    Slog.w(TAG, "No user info for user #" + userId);
17264                    return false;
17265                }
17266                if (foreground && userInfo.isManagedProfile()) {
17267                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17268                    return false;
17269                }
17270
17271                if (foreground) {
17272                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17273                            R.anim.screen_user_enter);
17274                }
17275
17276                boolean needStart = false;
17277
17278                // If the user we are switching to is not currently started, then
17279                // we need to start it now.
17280                if (mStartedUsers.get(userId) == null) {
17281                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17282                    updateStartedUserArrayLocked();
17283                    needStart = true;
17284                }
17285
17286                final Integer userIdInt = Integer.valueOf(userId);
17287                mUserLru.remove(userIdInt);
17288                mUserLru.add(userIdInt);
17289
17290                if (foreground) {
17291                    mCurrentUserId = userId;
17292                    updateCurrentProfileIdsLocked();
17293                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17294                    // Once the internal notion of the active user has switched, we lock the device
17295                    // with the option to show the user switcher on the keyguard.
17296                    mWindowManager.lockNow(null);
17297                } else {
17298                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17299                    updateCurrentProfileIdsLocked();
17300                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17301                    mUserLru.remove(currentUserIdInt);
17302                    mUserLru.add(currentUserIdInt);
17303                }
17304
17305                final UserStartedState uss = mStartedUsers.get(userId);
17306
17307                // Make sure user is in the started state.  If it is currently
17308                // stopping, we need to knock that off.
17309                if (uss.mState == UserStartedState.STATE_STOPPING) {
17310                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17311                    // so we can just fairly silently bring the user back from
17312                    // the almost-dead.
17313                    uss.mState = UserStartedState.STATE_RUNNING;
17314                    updateStartedUserArrayLocked();
17315                    needStart = true;
17316                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17317                    // This means ACTION_SHUTDOWN has been sent, so we will
17318                    // need to treat this as a new boot of the user.
17319                    uss.mState = UserStartedState.STATE_BOOTING;
17320                    updateStartedUserArrayLocked();
17321                    needStart = true;
17322                }
17323
17324                if (uss.mState == UserStartedState.STATE_BOOTING) {
17325                    // Booting up a new user, need to tell system services about it.
17326                    // Note that this is on the same handler as scheduling of broadcasts,
17327                    // which is important because it needs to go first.
17328                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17329                }
17330
17331                if (foreground) {
17332                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17333                            oldUserId));
17334                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17335                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17336                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17337                            oldUserId, userId, uss));
17338                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17339                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17340                }
17341
17342                if (needStart) {
17343                    // Send USER_STARTED broadcast
17344                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17345                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17346                            | Intent.FLAG_RECEIVER_FOREGROUND);
17347                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17348                    broadcastIntentLocked(null, null, intent,
17349                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17350                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17351                }
17352
17353                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17354                    if (userId != UserHandle.USER_OWNER) {
17355                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17356                        final ArrayList<ComponentName> doneReceivers
17357                                = new ArrayList<ComponentName>();
17358                        deliverPreBootCompleted(null, doneReceivers, userId);
17359
17360                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17361                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17362                        broadcastIntentLocked(null, null, intent, null,
17363                                new IIntentReceiver.Stub() {
17364                                    public void performReceive(Intent intent, int resultCode,
17365                                            String data, Bundle extras, boolean ordered,
17366                                            boolean sticky, int sendingUser) {
17367                                        userInitialized(uss, userId);
17368                                    }
17369                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17370                                true, false, MY_PID, Process.SYSTEM_UID,
17371                                userId);
17372                        uss.initializing = true;
17373                    } else {
17374                        getUserManagerLocked().makeInitialized(userInfo.id);
17375                    }
17376                }
17377
17378                if (foreground) {
17379                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17380                    if (homeInFront) {
17381                        startHomeActivityLocked(userId);
17382                    } else {
17383                        mStackSupervisor.resumeTopActivitiesLocked();
17384                    }
17385                    EventLogTags.writeAmSwitchUser(userId);
17386                    getUserManagerLocked().userForeground(userId);
17387                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17388                } else {
17389                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17390                }
17391
17392                if (needStart) {
17393                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17394                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17395                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17396                    broadcastIntentLocked(null, null, intent,
17397                            null, new IIntentReceiver.Stub() {
17398                                @Override
17399                                public void performReceive(Intent intent, int resultCode, String data,
17400                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17401                                        throws RemoteException {
17402                                }
17403                            }, 0, null, null,
17404                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17405                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17406                }
17407            }
17408        } finally {
17409            Binder.restoreCallingIdentity(ident);
17410        }
17411
17412        return true;
17413    }
17414
17415    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17416        long ident = Binder.clearCallingIdentity();
17417        try {
17418            Intent intent;
17419            if (oldUserId >= 0) {
17420                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17421                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17422                int count = profiles.size();
17423                for (int i = 0; i < count; i++) {
17424                    int profileUserId = profiles.get(i).id;
17425                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17426                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17427                            | Intent.FLAG_RECEIVER_FOREGROUND);
17428                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17429                    broadcastIntentLocked(null, null, intent,
17430                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17431                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17432                }
17433            }
17434            if (newUserId >= 0) {
17435                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17436                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17437                int count = profiles.size();
17438                for (int i = 0; i < count; i++) {
17439                    int profileUserId = profiles.get(i).id;
17440                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17441                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17442                            | Intent.FLAG_RECEIVER_FOREGROUND);
17443                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17444                    broadcastIntentLocked(null, null, intent,
17445                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17446                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17447                }
17448                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17449                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17450                        | Intent.FLAG_RECEIVER_FOREGROUND);
17451                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17452                broadcastIntentLocked(null, null, intent,
17453                        null, null, 0, null, null,
17454                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17455                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17456            }
17457        } finally {
17458            Binder.restoreCallingIdentity(ident);
17459        }
17460    }
17461
17462    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17463            final int newUserId) {
17464        final int N = mUserSwitchObservers.beginBroadcast();
17465        if (N > 0) {
17466            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17467                int mCount = 0;
17468                @Override
17469                public void sendResult(Bundle data) throws RemoteException {
17470                    synchronized (ActivityManagerService.this) {
17471                        if (mCurUserSwitchCallback == this) {
17472                            mCount++;
17473                            if (mCount == N) {
17474                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17475                            }
17476                        }
17477                    }
17478                }
17479            };
17480            synchronized (this) {
17481                uss.switching = true;
17482                mCurUserSwitchCallback = callback;
17483            }
17484            for (int i=0; i<N; i++) {
17485                try {
17486                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17487                            newUserId, callback);
17488                } catch (RemoteException e) {
17489                }
17490            }
17491        } else {
17492            synchronized (this) {
17493                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17494            }
17495        }
17496        mUserSwitchObservers.finishBroadcast();
17497    }
17498
17499    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17500        synchronized (this) {
17501            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17502            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17503        }
17504    }
17505
17506    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17507        mCurUserSwitchCallback = null;
17508        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17509        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17510                oldUserId, newUserId, uss));
17511    }
17512
17513    void userInitialized(UserStartedState uss, int newUserId) {
17514        completeSwitchAndInitalize(uss, newUserId, true, false);
17515    }
17516
17517    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17518        completeSwitchAndInitalize(uss, newUserId, false, true);
17519    }
17520
17521    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17522            boolean clearInitializing, boolean clearSwitching) {
17523        boolean unfrozen = false;
17524        synchronized (this) {
17525            if (clearInitializing) {
17526                uss.initializing = false;
17527                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17528            }
17529            if (clearSwitching) {
17530                uss.switching = false;
17531            }
17532            if (!uss.switching && !uss.initializing) {
17533                mWindowManager.stopFreezingScreen();
17534                unfrozen = true;
17535            }
17536        }
17537        if (unfrozen) {
17538            final int N = mUserSwitchObservers.beginBroadcast();
17539            for (int i=0; i<N; i++) {
17540                try {
17541                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17542                } catch (RemoteException e) {
17543                }
17544            }
17545            mUserSwitchObservers.finishBroadcast();
17546        }
17547    }
17548
17549    void scheduleStartProfilesLocked() {
17550        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17551            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17552                    DateUtils.SECOND_IN_MILLIS);
17553        }
17554    }
17555
17556    void startProfilesLocked() {
17557        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17558        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17559                mCurrentUserId, false /* enabledOnly */);
17560        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17561        for (UserInfo user : profiles) {
17562            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17563                    && user.id != mCurrentUserId) {
17564                toStart.add(user);
17565            }
17566        }
17567        final int n = toStart.size();
17568        int i = 0;
17569        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17570            startUserInBackground(toStart.get(i).id);
17571        }
17572        if (i < n) {
17573            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17574        }
17575    }
17576
17577    void finishUserBoot(UserStartedState uss) {
17578        synchronized (this) {
17579            if (uss.mState == UserStartedState.STATE_BOOTING
17580                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17581                uss.mState = UserStartedState.STATE_RUNNING;
17582                final int userId = uss.mHandle.getIdentifier();
17583                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17584                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17585                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17586                broadcastIntentLocked(null, null, intent,
17587                        null, null, 0, null, null,
17588                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17589                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17590            }
17591        }
17592    }
17593
17594    void finishUserSwitch(UserStartedState uss) {
17595        synchronized (this) {
17596            finishUserBoot(uss);
17597
17598            startProfilesLocked();
17599
17600            int num = mUserLru.size();
17601            int i = 0;
17602            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17603                Integer oldUserId = mUserLru.get(i);
17604                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17605                if (oldUss == null) {
17606                    // Shouldn't happen, but be sane if it does.
17607                    mUserLru.remove(i);
17608                    num--;
17609                    continue;
17610                }
17611                if (oldUss.mState == UserStartedState.STATE_STOPPING
17612                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17613                    // This user is already stopping, doesn't count.
17614                    num--;
17615                    i++;
17616                    continue;
17617                }
17618                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17619                    // Owner and current can't be stopped, but count as running.
17620                    i++;
17621                    continue;
17622                }
17623                // This is a user to be stopped.
17624                stopUserLocked(oldUserId, null);
17625                num--;
17626                i++;
17627            }
17628        }
17629    }
17630
17631    @Override
17632    public int stopUser(final int userId, final IStopUserCallback callback) {
17633        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17634                != PackageManager.PERMISSION_GRANTED) {
17635            String msg = "Permission Denial: switchUser() from pid="
17636                    + Binder.getCallingPid()
17637                    + ", uid=" + Binder.getCallingUid()
17638                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17639            Slog.w(TAG, msg);
17640            throw new SecurityException(msg);
17641        }
17642        if (userId <= 0) {
17643            throw new IllegalArgumentException("Can't stop primary user " + userId);
17644        }
17645        synchronized (this) {
17646            return stopUserLocked(userId, callback);
17647        }
17648    }
17649
17650    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17651        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17652        if (mCurrentUserId == userId) {
17653            return ActivityManager.USER_OP_IS_CURRENT;
17654        }
17655
17656        final UserStartedState uss = mStartedUsers.get(userId);
17657        if (uss == null) {
17658            // User is not started, nothing to do...  but we do need to
17659            // callback if requested.
17660            if (callback != null) {
17661                mHandler.post(new Runnable() {
17662                    @Override
17663                    public void run() {
17664                        try {
17665                            callback.userStopped(userId);
17666                        } catch (RemoteException e) {
17667                        }
17668                    }
17669                });
17670            }
17671            return ActivityManager.USER_OP_SUCCESS;
17672        }
17673
17674        if (callback != null) {
17675            uss.mStopCallbacks.add(callback);
17676        }
17677
17678        if (uss.mState != UserStartedState.STATE_STOPPING
17679                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17680            uss.mState = UserStartedState.STATE_STOPPING;
17681            updateStartedUserArrayLocked();
17682
17683            long ident = Binder.clearCallingIdentity();
17684            try {
17685                // We are going to broadcast ACTION_USER_STOPPING and then
17686                // once that is done send a final ACTION_SHUTDOWN and then
17687                // stop the user.
17688                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17689                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17690                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17691                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17692                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17693                // This is the result receiver for the final shutdown broadcast.
17694                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17695                    @Override
17696                    public void performReceive(Intent intent, int resultCode, String data,
17697                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17698                        finishUserStop(uss);
17699                    }
17700                };
17701                // This is the result receiver for the initial stopping broadcast.
17702                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17703                    @Override
17704                    public void performReceive(Intent intent, int resultCode, String data,
17705                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17706                        // On to the next.
17707                        synchronized (ActivityManagerService.this) {
17708                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17709                                // Whoops, we are being started back up.  Abort, abort!
17710                                return;
17711                            }
17712                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17713                        }
17714                        mBatteryStatsService.noteEvent(
17715                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17716                                Integer.toString(userId), userId);
17717                        mSystemServiceManager.stopUser(userId);
17718                        broadcastIntentLocked(null, null, shutdownIntent,
17719                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17720                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17721                    }
17722                };
17723                // Kick things off.
17724                broadcastIntentLocked(null, null, stoppingIntent,
17725                        null, stoppingReceiver, 0, null, null,
17726                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17727                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17728            } finally {
17729                Binder.restoreCallingIdentity(ident);
17730            }
17731        }
17732
17733        return ActivityManager.USER_OP_SUCCESS;
17734    }
17735
17736    void finishUserStop(UserStartedState uss) {
17737        final int userId = uss.mHandle.getIdentifier();
17738        boolean stopped;
17739        ArrayList<IStopUserCallback> callbacks;
17740        synchronized (this) {
17741            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17742            if (mStartedUsers.get(userId) != uss) {
17743                stopped = false;
17744            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17745                stopped = false;
17746            } else {
17747                stopped = true;
17748                // User can no longer run.
17749                mStartedUsers.remove(userId);
17750                mUserLru.remove(Integer.valueOf(userId));
17751                updateStartedUserArrayLocked();
17752
17753                // Clean up all state and processes associated with the user.
17754                // Kill all the processes for the user.
17755                forceStopUserLocked(userId, "finish user");
17756            }
17757
17758            // Explicitly remove the old information in mRecentTasks.
17759            removeRecentTasksForUserLocked(userId);
17760        }
17761
17762        for (int i=0; i<callbacks.size(); i++) {
17763            try {
17764                if (stopped) callbacks.get(i).userStopped(userId);
17765                else callbacks.get(i).userStopAborted(userId);
17766            } catch (RemoteException e) {
17767            }
17768        }
17769
17770        if (stopped) {
17771            mSystemServiceManager.cleanupUser(userId);
17772            synchronized (this) {
17773                mStackSupervisor.removeUserLocked(userId);
17774            }
17775        }
17776    }
17777
17778    @Override
17779    public UserInfo getCurrentUser() {
17780        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17781                != PackageManager.PERMISSION_GRANTED) && (
17782                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17783                != PackageManager.PERMISSION_GRANTED)) {
17784            String msg = "Permission Denial: getCurrentUser() from pid="
17785                    + Binder.getCallingPid()
17786                    + ", uid=" + Binder.getCallingUid()
17787                    + " requires " + INTERACT_ACROSS_USERS;
17788            Slog.w(TAG, msg);
17789            throw new SecurityException(msg);
17790        }
17791        synchronized (this) {
17792            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17793        }
17794    }
17795
17796    int getCurrentUserIdLocked() {
17797        return mCurrentUserId;
17798    }
17799
17800    @Override
17801    public boolean isUserRunning(int userId, boolean orStopped) {
17802        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17803                != PackageManager.PERMISSION_GRANTED) {
17804            String msg = "Permission Denial: isUserRunning() from pid="
17805                    + Binder.getCallingPid()
17806                    + ", uid=" + Binder.getCallingUid()
17807                    + " requires " + INTERACT_ACROSS_USERS;
17808            Slog.w(TAG, msg);
17809            throw new SecurityException(msg);
17810        }
17811        synchronized (this) {
17812            return isUserRunningLocked(userId, orStopped);
17813        }
17814    }
17815
17816    boolean isUserRunningLocked(int userId, boolean orStopped) {
17817        UserStartedState state = mStartedUsers.get(userId);
17818        if (state == null) {
17819            return false;
17820        }
17821        if (orStopped) {
17822            return true;
17823        }
17824        return state.mState != UserStartedState.STATE_STOPPING
17825                && state.mState != UserStartedState.STATE_SHUTDOWN;
17826    }
17827
17828    @Override
17829    public int[] getRunningUserIds() {
17830        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17831                != PackageManager.PERMISSION_GRANTED) {
17832            String msg = "Permission Denial: isUserRunning() from pid="
17833                    + Binder.getCallingPid()
17834                    + ", uid=" + Binder.getCallingUid()
17835                    + " requires " + INTERACT_ACROSS_USERS;
17836            Slog.w(TAG, msg);
17837            throw new SecurityException(msg);
17838        }
17839        synchronized (this) {
17840            return mStartedUserArray;
17841        }
17842    }
17843
17844    private void updateStartedUserArrayLocked() {
17845        int num = 0;
17846        for (int i=0; i<mStartedUsers.size();  i++) {
17847            UserStartedState uss = mStartedUsers.valueAt(i);
17848            // This list does not include stopping users.
17849            if (uss.mState != UserStartedState.STATE_STOPPING
17850                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17851                num++;
17852            }
17853        }
17854        mStartedUserArray = new int[num];
17855        num = 0;
17856        for (int i=0; i<mStartedUsers.size();  i++) {
17857            UserStartedState uss = mStartedUsers.valueAt(i);
17858            if (uss.mState != UserStartedState.STATE_STOPPING
17859                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17860                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17861                num++;
17862            }
17863        }
17864    }
17865
17866    @Override
17867    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17868        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17869                != PackageManager.PERMISSION_GRANTED) {
17870            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17871                    + Binder.getCallingPid()
17872                    + ", uid=" + Binder.getCallingUid()
17873                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17874            Slog.w(TAG, msg);
17875            throw new SecurityException(msg);
17876        }
17877
17878        mUserSwitchObservers.register(observer);
17879    }
17880
17881    @Override
17882    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17883        mUserSwitchObservers.unregister(observer);
17884    }
17885
17886    private boolean userExists(int userId) {
17887        if (userId == 0) {
17888            return true;
17889        }
17890        UserManagerService ums = getUserManagerLocked();
17891        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17892    }
17893
17894    int[] getUsersLocked() {
17895        UserManagerService ums = getUserManagerLocked();
17896        return ums != null ? ums.getUserIds() : new int[] { 0 };
17897    }
17898
17899    UserManagerService getUserManagerLocked() {
17900        if (mUserManager == null) {
17901            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17902            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17903        }
17904        return mUserManager;
17905    }
17906
17907    private int applyUserId(int uid, int userId) {
17908        return UserHandle.getUid(userId, uid);
17909    }
17910
17911    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17912        if (info == null) return null;
17913        ApplicationInfo newInfo = new ApplicationInfo(info);
17914        newInfo.uid = applyUserId(info.uid, userId);
17915        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17916                + info.packageName;
17917        return newInfo;
17918    }
17919
17920    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17921        if (aInfo == null
17922                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17923            return aInfo;
17924        }
17925
17926        ActivityInfo info = new ActivityInfo(aInfo);
17927        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17928        return info;
17929    }
17930
17931    private final class LocalService extends ActivityManagerInternal {
17932        @Override
17933        public void goingToSleep() {
17934            ActivityManagerService.this.goingToSleep();
17935        }
17936
17937        @Override
17938        public void wakingUp() {
17939            ActivityManagerService.this.wakingUp();
17940        }
17941
17942        @Override
17943        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
17944                String processName, String abiOverride, int uid, Runnable crashHandler) {
17945            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
17946                    processName, abiOverride, uid, crashHandler);
17947        }
17948    }
17949
17950    /**
17951     * An implementation of IAppTask, that allows an app to manage its own tasks via
17952     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17953     * only the process that calls getAppTasks() can call the AppTask methods.
17954     */
17955    class AppTaskImpl extends IAppTask.Stub {
17956        private int mTaskId;
17957        private int mCallingUid;
17958
17959        public AppTaskImpl(int taskId, int callingUid) {
17960            mTaskId = taskId;
17961            mCallingUid = callingUid;
17962        }
17963
17964        @Override
17965        public void finishAndRemoveTask() {
17966            // Ensure that we are called from the same process that created this AppTask
17967            if (mCallingUid != Binder.getCallingUid()) {
17968                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17969                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17970                return;
17971            }
17972
17973            synchronized (ActivityManagerService.this) {
17974                long origId = Binder.clearCallingIdentity();
17975                try {
17976                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17977                    if (tr != null) {
17978                        // Only kill the process if we are not a new document
17979                        int flags = tr.getBaseIntent().getFlags();
17980                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17981                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17982                        removeTaskByIdLocked(mTaskId,
17983                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17984                    }
17985                } finally {
17986                    Binder.restoreCallingIdentity(origId);
17987                }
17988            }
17989        }
17990
17991        @Override
17992        public ActivityManager.RecentTaskInfo getTaskInfo() {
17993            // Ensure that we are called from the same process that created this AppTask
17994            if (mCallingUid != Binder.getCallingUid()) {
17995                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17996                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17997                return null;
17998            }
17999
18000            synchronized (ActivityManagerService.this) {
18001                long origId = Binder.clearCallingIdentity();
18002                try {
18003                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18004                    if (tr != null) {
18005                        return createRecentTaskInfoFromTaskRecord(tr);
18006                    }
18007                } finally {
18008                    Binder.restoreCallingIdentity(origId);
18009                }
18010                return null;
18011            }
18012        }
18013    }
18014}
18015