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