ActivityManagerService.java revision 6d2a9492e2b19421165f0cd918d9f28595bfb770
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.UsageEvents;
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(systemDir, mHandler);
2204        mBatteryStatsService.getActiveStatistics().readLocked();
2205        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2206        mOnBattery = DEBUG_POWER ? true
2207                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2208        mBatteryStatsService.getActiveStatistics().setCallback(this);
2209
2210        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2211
2212        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2213
2214        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2215
2216        // User 0 is the first and only user that runs at boot.
2217        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2218        mUserLru.add(Integer.valueOf(0));
2219        updateStartedUserArrayLocked();
2220
2221        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2222            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2223
2224        mConfiguration.setToDefaults();
2225        mConfiguration.setLocale(Locale.getDefault());
2226
2227        mConfigurationSeq = mConfiguration.seq = 1;
2228        mProcessCpuTracker.init();
2229
2230        mHasRecents = mContext.getResources().getBoolean(
2231                com.android.internal.R.bool.config_hasRecents);
2232
2233        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2234        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2235        mStackSupervisor = new ActivityStackSupervisor(this);
2236        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2237
2238        mProcessCpuThread = new Thread("CpuTracker") {
2239            @Override
2240            public void run() {
2241                while (true) {
2242                    try {
2243                        try {
2244                            synchronized(this) {
2245                                final long now = SystemClock.uptimeMillis();
2246                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2247                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2248                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2249                                //        + ", write delay=" + nextWriteDelay);
2250                                if (nextWriteDelay < nextCpuDelay) {
2251                                    nextCpuDelay = nextWriteDelay;
2252                                }
2253                                if (nextCpuDelay > 0) {
2254                                    mProcessCpuMutexFree.set(true);
2255                                    this.wait(nextCpuDelay);
2256                                }
2257                            }
2258                        } catch (InterruptedException e) {
2259                        }
2260                        updateCpuStatsNow();
2261                    } catch (Exception e) {
2262                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2263                    }
2264                }
2265            }
2266        };
2267
2268        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2269
2270        Watchdog.getInstance().addMonitor(this);
2271        Watchdog.getInstance().addThread(mHandler);
2272    }
2273
2274    public void setSystemServiceManager(SystemServiceManager mgr) {
2275        mSystemServiceManager = mgr;
2276    }
2277
2278    private void start() {
2279        Process.removeAllProcessGroups();
2280        mProcessCpuThread.start();
2281
2282        mBatteryStatsService.publish(mContext);
2283        mAppOpsService.publish(mContext);
2284        Slog.d("AppOps", "AppOpsService published");
2285        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2286    }
2287
2288    public void initPowerManagement() {
2289        mStackSupervisor.initPowerManagement();
2290        mBatteryStatsService.initPowerManagement();
2291    }
2292
2293    @Override
2294    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2295            throws RemoteException {
2296        if (code == SYSPROPS_TRANSACTION) {
2297            // We need to tell all apps about the system property change.
2298            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2299            synchronized(this) {
2300                final int NP = mProcessNames.getMap().size();
2301                for (int ip=0; ip<NP; ip++) {
2302                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2303                    final int NA = apps.size();
2304                    for (int ia=0; ia<NA; ia++) {
2305                        ProcessRecord app = apps.valueAt(ia);
2306                        if (app.thread != null) {
2307                            procs.add(app.thread.asBinder());
2308                        }
2309                    }
2310                }
2311            }
2312
2313            int N = procs.size();
2314            for (int i=0; i<N; i++) {
2315                Parcel data2 = Parcel.obtain();
2316                try {
2317                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2318                } catch (RemoteException e) {
2319                }
2320                data2.recycle();
2321            }
2322        }
2323        try {
2324            return super.onTransact(code, data, reply, flags);
2325        } catch (RuntimeException e) {
2326            // The activity manager only throws security exceptions, so let's
2327            // log all others.
2328            if (!(e instanceof SecurityException)) {
2329                Slog.wtf(TAG, "Activity Manager Crash", e);
2330            }
2331            throw e;
2332        }
2333    }
2334
2335    void updateCpuStats() {
2336        final long now = SystemClock.uptimeMillis();
2337        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2338            return;
2339        }
2340        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2341            synchronized (mProcessCpuThread) {
2342                mProcessCpuThread.notify();
2343            }
2344        }
2345    }
2346
2347    void updateCpuStatsNow() {
2348        synchronized (mProcessCpuThread) {
2349            mProcessCpuMutexFree.set(false);
2350            final long now = SystemClock.uptimeMillis();
2351            boolean haveNewCpuStats = false;
2352
2353            if (MONITOR_CPU_USAGE &&
2354                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2355                mLastCpuTime.set(now);
2356                haveNewCpuStats = true;
2357                mProcessCpuTracker.update();
2358                //Slog.i(TAG, mProcessCpu.printCurrentState());
2359                //Slog.i(TAG, "Total CPU usage: "
2360                //        + mProcessCpu.getTotalCpuPercent() + "%");
2361
2362                // Slog the cpu usage if the property is set.
2363                if ("true".equals(SystemProperties.get("events.cpu"))) {
2364                    int user = mProcessCpuTracker.getLastUserTime();
2365                    int system = mProcessCpuTracker.getLastSystemTime();
2366                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2367                    int irq = mProcessCpuTracker.getLastIrqTime();
2368                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2369                    int idle = mProcessCpuTracker.getLastIdleTime();
2370
2371                    int total = user + system + iowait + irq + softIrq + idle;
2372                    if (total == 0) total = 1;
2373
2374                    EventLog.writeEvent(EventLogTags.CPU,
2375                            ((user+system+iowait+irq+softIrq) * 100) / total,
2376                            (user * 100) / total,
2377                            (system * 100) / total,
2378                            (iowait * 100) / total,
2379                            (irq * 100) / total,
2380                            (softIrq * 100) / total);
2381                }
2382            }
2383
2384            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2385            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2386            synchronized(bstats) {
2387                synchronized(mPidsSelfLocked) {
2388                    if (haveNewCpuStats) {
2389                        if (mOnBattery) {
2390                            int perc = bstats.startAddingCpuLocked();
2391                            int totalUTime = 0;
2392                            int totalSTime = 0;
2393                            final int N = mProcessCpuTracker.countStats();
2394                            for (int i=0; i<N; i++) {
2395                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2396                                if (!st.working) {
2397                                    continue;
2398                                }
2399                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2400                                int otherUTime = (st.rel_utime*perc)/100;
2401                                int otherSTime = (st.rel_stime*perc)/100;
2402                                totalUTime += otherUTime;
2403                                totalSTime += otherSTime;
2404                                if (pr != null) {
2405                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2406                                    if (ps == null || !ps.isActive()) {
2407                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2408                                                pr.info.uid, pr.processName);
2409                                    }
2410                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2411                                            st.rel_stime-otherSTime);
2412                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2413                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2414                                } else {
2415                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2416                                    if (ps == null || !ps.isActive()) {
2417                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2418                                                bstats.mapUid(st.uid), st.name);
2419                                    }
2420                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2421                                            st.rel_stime-otherSTime);
2422                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2423                                }
2424                            }
2425                            bstats.finishAddingCpuLocked(perc, totalUTime,
2426                                    totalSTime, cpuSpeedTimes);
2427                        }
2428                    }
2429                }
2430
2431                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2432                    mLastWriteTime = now;
2433                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2434                }
2435            }
2436        }
2437    }
2438
2439    @Override
2440    public void batteryNeedsCpuUpdate() {
2441        updateCpuStatsNow();
2442    }
2443
2444    @Override
2445    public void batteryPowerChanged(boolean onBattery) {
2446        // When plugging in, update the CPU stats first before changing
2447        // the plug state.
2448        updateCpuStatsNow();
2449        synchronized (this) {
2450            synchronized(mPidsSelfLocked) {
2451                mOnBattery = DEBUG_POWER ? true : onBattery;
2452            }
2453        }
2454    }
2455
2456    /**
2457     * Initialize the application bind args. These are passed to each
2458     * process when the bindApplication() IPC is sent to the process. They're
2459     * lazily setup to make sure the services are running when they're asked for.
2460     */
2461    private HashMap<String, IBinder> getCommonServicesLocked() {
2462        if (mAppBindArgs == null) {
2463            mAppBindArgs = new HashMap<String, IBinder>();
2464
2465            // Setup the application init args
2466            mAppBindArgs.put("package", ServiceManager.getService("package"));
2467            mAppBindArgs.put("window", ServiceManager.getService("window"));
2468            mAppBindArgs.put(Context.ALARM_SERVICE,
2469                    ServiceManager.getService(Context.ALARM_SERVICE));
2470        }
2471        return mAppBindArgs;
2472    }
2473
2474    final void setFocusedActivityLocked(ActivityRecord r) {
2475        if (mFocusedActivity != r) {
2476            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2477            mFocusedActivity = r;
2478            if (r.task != null && r.task.voiceInteractor != null) {
2479                startRunningVoiceLocked();
2480            } else {
2481                finishRunningVoiceLocked();
2482            }
2483            mStackSupervisor.setFocusedStack(r);
2484            if (r != null) {
2485                mWindowManager.setFocusedApp(r.appToken, true);
2486            }
2487            applyUpdateLockStateLocked(r);
2488        }
2489    }
2490
2491    final void clearFocusedActivity(ActivityRecord r) {
2492        if (mFocusedActivity == r) {
2493            mFocusedActivity = null;
2494        }
2495    }
2496
2497    @Override
2498    public void setFocusedStack(int stackId) {
2499        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2500        synchronized (ActivityManagerService.this) {
2501            ActivityStack stack = mStackSupervisor.getStack(stackId);
2502            if (stack != null) {
2503                ActivityRecord r = stack.topRunningActivityLocked(null);
2504                if (r != null) {
2505                    setFocusedActivityLocked(r);
2506                }
2507            }
2508        }
2509    }
2510
2511    @Override
2512    public void notifyActivityDrawn(IBinder token) {
2513        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2514        synchronized (this) {
2515            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2516            if (r != null) {
2517                r.task.stack.notifyActivityDrawnLocked(r);
2518            }
2519        }
2520    }
2521
2522    final void applyUpdateLockStateLocked(ActivityRecord r) {
2523        // Modifications to the UpdateLock state are done on our handler, outside
2524        // the activity manager's locks.  The new state is determined based on the
2525        // state *now* of the relevant activity record.  The object is passed to
2526        // the handler solely for logging detail, not to be consulted/modified.
2527        final boolean nextState = r != null && r.immersive;
2528        mHandler.sendMessage(
2529                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2530    }
2531
2532    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2533        Message msg = Message.obtain();
2534        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2535        msg.obj = r.task.askedCompatMode ? null : r;
2536        mHandler.sendMessage(msg);
2537    }
2538
2539    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2540            String what, Object obj, ProcessRecord srcApp) {
2541        app.lastActivityTime = now;
2542
2543        if (app.activities.size() > 0) {
2544            // Don't want to touch dependent processes that are hosting activities.
2545            return index;
2546        }
2547
2548        int lrui = mLruProcesses.lastIndexOf(app);
2549        if (lrui < 0) {
2550            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2551                    + what + " " + obj + " from " + srcApp);
2552            return index;
2553        }
2554
2555        if (lrui >= index) {
2556            // Don't want to cause this to move dependent processes *back* in the
2557            // list as if they were less frequently used.
2558            return index;
2559        }
2560
2561        if (lrui >= mLruProcessActivityStart) {
2562            // Don't want to touch dependent processes that are hosting activities.
2563            return index;
2564        }
2565
2566        mLruProcesses.remove(lrui);
2567        if (index > 0) {
2568            index--;
2569        }
2570        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2571                + " in LRU list: " + app);
2572        mLruProcesses.add(index, app);
2573        return index;
2574    }
2575
2576    final void removeLruProcessLocked(ProcessRecord app) {
2577        int lrui = mLruProcesses.lastIndexOf(app);
2578        if (lrui >= 0) {
2579            if (lrui <= mLruProcessActivityStart) {
2580                mLruProcessActivityStart--;
2581            }
2582            if (lrui <= mLruProcessServiceStart) {
2583                mLruProcessServiceStart--;
2584            }
2585            mLruProcesses.remove(lrui);
2586        }
2587    }
2588
2589    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2590            ProcessRecord client) {
2591        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2592                || app.treatLikeActivity;
2593        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2594        if (!activityChange && hasActivity) {
2595            // The process has activities, so we are only allowing activity-based adjustments
2596            // to move it.  It should be kept in the front of the list with other
2597            // processes that have activities, and we don't want those to change their
2598            // order except due to activity operations.
2599            return;
2600        }
2601
2602        mLruSeq++;
2603        final long now = SystemClock.uptimeMillis();
2604        app.lastActivityTime = now;
2605
2606        // First a quick reject: if the app is already at the position we will
2607        // put it, then there is nothing to do.
2608        if (hasActivity) {
2609            final int N = mLruProcesses.size();
2610            if (N > 0 && mLruProcesses.get(N-1) == app) {
2611                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2612                return;
2613            }
2614        } else {
2615            if (mLruProcessServiceStart > 0
2616                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2617                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2618                return;
2619            }
2620        }
2621
2622        int lrui = mLruProcesses.lastIndexOf(app);
2623
2624        if (app.persistent && lrui >= 0) {
2625            // We don't care about the position of persistent processes, as long as
2626            // they are in the list.
2627            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2628            return;
2629        }
2630
2631        /* In progress: compute new position first, so we can avoid doing work
2632           if the process is not actually going to move.  Not yet working.
2633        int addIndex;
2634        int nextIndex;
2635        boolean inActivity = false, inService = false;
2636        if (hasActivity) {
2637            // Process has activities, put it at the very tipsy-top.
2638            addIndex = mLruProcesses.size();
2639            nextIndex = mLruProcessServiceStart;
2640            inActivity = true;
2641        } else if (hasService) {
2642            // Process has services, put it at the top of the service list.
2643            addIndex = mLruProcessActivityStart;
2644            nextIndex = mLruProcessServiceStart;
2645            inActivity = true;
2646            inService = true;
2647        } else  {
2648            // Process not otherwise of interest, it goes to the top of the non-service area.
2649            addIndex = mLruProcessServiceStart;
2650            if (client != null) {
2651                int clientIndex = mLruProcesses.lastIndexOf(client);
2652                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2653                        + app);
2654                if (clientIndex >= 0 && addIndex > clientIndex) {
2655                    addIndex = clientIndex;
2656                }
2657            }
2658            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2659        }
2660
2661        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2662                + mLruProcessActivityStart + "): " + app);
2663        */
2664
2665        if (lrui >= 0) {
2666            if (lrui < mLruProcessActivityStart) {
2667                mLruProcessActivityStart--;
2668            }
2669            if (lrui < mLruProcessServiceStart) {
2670                mLruProcessServiceStart--;
2671            }
2672            /*
2673            if (addIndex > lrui) {
2674                addIndex--;
2675            }
2676            if (nextIndex > lrui) {
2677                nextIndex--;
2678            }
2679            */
2680            mLruProcesses.remove(lrui);
2681        }
2682
2683        /*
2684        mLruProcesses.add(addIndex, app);
2685        if (inActivity) {
2686            mLruProcessActivityStart++;
2687        }
2688        if (inService) {
2689            mLruProcessActivityStart++;
2690        }
2691        */
2692
2693        int nextIndex;
2694        if (hasActivity) {
2695            final int N = mLruProcesses.size();
2696            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2697                // Process doesn't have activities, but has clients with
2698                // activities...  move it up, but one below the top (the top
2699                // should always have a real activity).
2700                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2701                mLruProcesses.add(N-1, app);
2702                // To keep it from spamming the LRU list (by making a bunch of clients),
2703                // we will push down any other entries owned by the app.
2704                final int uid = app.info.uid;
2705                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2706                    ProcessRecord subProc = mLruProcesses.get(i);
2707                    if (subProc.info.uid == uid) {
2708                        // We want to push this one down the list.  If the process after
2709                        // it is for the same uid, however, don't do so, because we don't
2710                        // want them internally to be re-ordered.
2711                        if (mLruProcesses.get(i-1).info.uid != uid) {
2712                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2713                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2714                            ProcessRecord tmp = mLruProcesses.get(i);
2715                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2716                            mLruProcesses.set(i-1, tmp);
2717                            i--;
2718                        }
2719                    } else {
2720                        // A gap, we can stop here.
2721                        break;
2722                    }
2723                }
2724            } else {
2725                // Process has activities, put it at the very tipsy-top.
2726                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2727                mLruProcesses.add(app);
2728            }
2729            nextIndex = mLruProcessServiceStart;
2730        } else if (hasService) {
2731            // Process has services, put it at the top of the service list.
2732            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2733            mLruProcesses.add(mLruProcessActivityStart, app);
2734            nextIndex = mLruProcessServiceStart;
2735            mLruProcessActivityStart++;
2736        } else  {
2737            // Process not otherwise of interest, it goes to the top of the non-service area.
2738            int index = mLruProcessServiceStart;
2739            if (client != null) {
2740                // If there is a client, don't allow the process to be moved up higher
2741                // in the list than that client.
2742                int clientIndex = mLruProcesses.lastIndexOf(client);
2743                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2744                        + " when updating " + app);
2745                if (clientIndex <= lrui) {
2746                    // Don't allow the client index restriction to push it down farther in the
2747                    // list than it already is.
2748                    clientIndex = lrui;
2749                }
2750                if (clientIndex >= 0 && index > clientIndex) {
2751                    index = clientIndex;
2752                }
2753            }
2754            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2755            mLruProcesses.add(index, app);
2756            nextIndex = index-1;
2757            mLruProcessActivityStart++;
2758            mLruProcessServiceStart++;
2759        }
2760
2761        // If the app is currently using a content provider or service,
2762        // bump those processes as well.
2763        for (int j=app.connections.size()-1; j>=0; j--) {
2764            ConnectionRecord cr = app.connections.valueAt(j);
2765            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2766                    && cr.binding.service.app != null
2767                    && cr.binding.service.app.lruSeq != mLruSeq
2768                    && !cr.binding.service.app.persistent) {
2769                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2770                        "service connection", cr, app);
2771            }
2772        }
2773        for (int j=app.conProviders.size()-1; j>=0; j--) {
2774            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2775            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2776                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2777                        "provider reference", cpr, app);
2778            }
2779        }
2780    }
2781
2782    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2783        if (uid == Process.SYSTEM_UID) {
2784            // The system gets to run in any process.  If there are multiple
2785            // processes with the same uid, just pick the first (this
2786            // should never happen).
2787            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2788            if (procs == null) return null;
2789            final int N = procs.size();
2790            for (int i = 0; i < N; i++) {
2791                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2792            }
2793        }
2794        ProcessRecord proc = mProcessNames.get(processName, uid);
2795        if (false && proc != null && !keepIfLarge
2796                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2797                && proc.lastCachedPss >= 4000) {
2798            // Turn this condition on to cause killing to happen regularly, for testing.
2799            if (proc.baseProcessTracker != null) {
2800                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2801            }
2802            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2803                    + "k from cached");
2804        } else if (proc != null && !keepIfLarge
2805                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2806                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2807            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2808            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2809                if (proc.baseProcessTracker != null) {
2810                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2811                }
2812                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2813                        + "k from cached");
2814            }
2815        }
2816        return proc;
2817    }
2818
2819    void ensurePackageDexOpt(String packageName) {
2820        IPackageManager pm = AppGlobals.getPackageManager();
2821        try {
2822            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2823                mDidDexOpt = true;
2824            }
2825        } catch (RemoteException e) {
2826        }
2827    }
2828
2829    boolean isNextTransitionForward() {
2830        int transit = mWindowManager.getPendingAppTransition();
2831        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2832                || transit == AppTransition.TRANSIT_TASK_OPEN
2833                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2834    }
2835
2836    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2837            String processName, String abiOverride, int uid, Runnable crashHandler) {
2838        synchronized(this) {
2839            ApplicationInfo info = new ApplicationInfo();
2840            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2841            // For isolated processes, the former contains the parent's uid and the latter the
2842            // actual uid of the isolated process.
2843            // In the special case introduced by this method (which is, starting an isolated
2844            // process directly from the SystemServer without an actual parent app process) the
2845            // closest thing to a parent's uid is SYSTEM_UID.
2846            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2847            // the |isolated| logic in the ProcessRecord constructor.
2848            info.uid = Process.SYSTEM_UID;
2849            info.processName = processName;
2850            info.className = entryPoint;
2851            info.packageName = "android";
2852            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2853                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2854                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2855                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2856                    crashHandler);
2857            return proc != null ? proc.pid : 0;
2858        }
2859    }
2860
2861    final ProcessRecord startProcessLocked(String processName,
2862            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2863            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2864            boolean isolated, boolean keepIfLarge) {
2865        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2866                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2867                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2868                null /* crashHandler */);
2869    }
2870
2871    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2872            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2873            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2874            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2875        ProcessRecord app;
2876        if (!isolated) {
2877            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2878        } else {
2879            // If this is an isolated process, it can't re-use an existing process.
2880            app = null;
2881        }
2882        // We don't have to do anything more if:
2883        // (1) There is an existing application record; and
2884        // (2) The caller doesn't think it is dead, OR there is no thread
2885        //     object attached to it so we know it couldn't have crashed; and
2886        // (3) There is a pid assigned to it, so it is either starting or
2887        //     already running.
2888        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2889                + " app=" + app + " knownToBeDead=" + knownToBeDead
2890                + " thread=" + (app != null ? app.thread : null)
2891                + " pid=" + (app != null ? app.pid : -1));
2892        if (app != null && app.pid > 0) {
2893            if (!knownToBeDead || app.thread == null) {
2894                // We already have the app running, or are waiting for it to
2895                // come up (we have a pid but not yet its thread), so keep it.
2896                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2897                // If this is a new package in the process, add the package to the list
2898                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2899                return app;
2900            }
2901
2902            // An application record is attached to a previous process,
2903            // clean it up now.
2904            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2905            Process.killProcessGroup(app.info.uid, app.pid);
2906            handleAppDiedLocked(app, true, true);
2907        }
2908
2909        String hostingNameStr = hostingName != null
2910                ? hostingName.flattenToShortString() : null;
2911
2912        if (!isolated) {
2913            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2914                // If we are in the background, then check to see if this process
2915                // is bad.  If so, we will just silently fail.
2916                if (mBadProcesses.get(info.processName, info.uid) != null) {
2917                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2918                            + "/" + info.processName);
2919                    return null;
2920                }
2921            } else {
2922                // When the user is explicitly starting a process, then clear its
2923                // crash count so that we won't make it bad until they see at
2924                // least one crash dialog again, and make the process good again
2925                // if it had been bad.
2926                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2927                        + "/" + info.processName);
2928                mProcessCrashTimes.remove(info.processName, info.uid);
2929                if (mBadProcesses.get(info.processName, info.uid) != null) {
2930                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2931                            UserHandle.getUserId(info.uid), info.uid,
2932                            info.processName);
2933                    mBadProcesses.remove(info.processName, info.uid);
2934                    if (app != null) {
2935                        app.bad = false;
2936                    }
2937                }
2938            }
2939        }
2940
2941        if (app == null) {
2942            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2943            app.crashHandler = crashHandler;
2944            if (app == null) {
2945                Slog.w(TAG, "Failed making new process record for "
2946                        + processName + "/" + info.uid + " isolated=" + isolated);
2947                return null;
2948            }
2949            mProcessNames.put(processName, app.uid, app);
2950            if (isolated) {
2951                mIsolatedProcesses.put(app.uid, app);
2952            }
2953        } else {
2954            // If this is a new package in the process, add the package to the list
2955            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2956        }
2957
2958        // If the system is not ready yet, then hold off on starting this
2959        // process until it is.
2960        if (!mProcessesReady
2961                && !isAllowedWhileBooting(info)
2962                && !allowWhileBooting) {
2963            if (!mProcessesOnHold.contains(app)) {
2964                mProcessesOnHold.add(app);
2965            }
2966            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2967            return app;
2968        }
2969
2970        startProcessLocked(
2971                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2972        return (app.pid != 0) ? app : null;
2973    }
2974
2975    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2976        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2977    }
2978
2979    private final void startProcessLocked(ProcessRecord app,
2980            String hostingType, String hostingNameStr) {
2981        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
2982                null /* entryPoint */, null /* entryPointArgs */);
2983    }
2984
2985    private final void startProcessLocked(ProcessRecord app, String hostingType,
2986            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2987        if (app.pid > 0 && app.pid != MY_PID) {
2988            synchronized (mPidsSelfLocked) {
2989                mPidsSelfLocked.remove(app.pid);
2990                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2991            }
2992            app.setPid(0);
2993        }
2994
2995        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2996                "startProcessLocked removing on hold: " + app);
2997        mProcessesOnHold.remove(app);
2998
2999        updateCpuStats();
3000
3001        try {
3002            int uid = app.uid;
3003
3004            int[] gids = null;
3005            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3006            if (!app.isolated) {
3007                int[] permGids = null;
3008                try {
3009                    final PackageManager pm = mContext.getPackageManager();
3010                    permGids = pm.getPackageGids(app.info.packageName);
3011
3012                    if (Environment.isExternalStorageEmulated()) {
3013                        if (pm.checkPermission(
3014                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3015                                app.info.packageName) == PERMISSION_GRANTED) {
3016                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3017                        } else {
3018                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3019                        }
3020                    }
3021                } catch (PackageManager.NameNotFoundException e) {
3022                    Slog.w(TAG, "Unable to retrieve gids", e);
3023                }
3024
3025                /*
3026                 * Add shared application and profile GIDs so applications can share some
3027                 * resources like shared libraries and access user-wide resources
3028                 */
3029                if (permGids == null) {
3030                    gids = new int[2];
3031                } else {
3032                    gids = new int[permGids.length + 2];
3033                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3034                }
3035                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3036                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3037            }
3038            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3039                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3040                        && mTopComponent != null
3041                        && app.processName.equals(mTopComponent.getPackageName())) {
3042                    uid = 0;
3043                }
3044                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3045                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3046                    uid = 0;
3047                }
3048            }
3049            int debugFlags = 0;
3050            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3051                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3052                // Also turn on CheckJNI for debuggable apps. It's quite
3053                // awkward to turn on otherwise.
3054                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3055            }
3056            // Run the app in safe mode if its manifest requests so or the
3057            // system is booted in safe mode.
3058            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3059                mSafeMode == true) {
3060                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3061            }
3062            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3063                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3064            }
3065            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3066                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3067            }
3068            if ("1".equals(SystemProperties.get("debug.assert"))) {
3069                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3070            }
3071
3072            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3073            if (requiredAbi == null) {
3074                requiredAbi = Build.SUPPORTED_ABIS[0];
3075            }
3076
3077            // Start the process.  It will either succeed and return a result containing
3078            // the PID of the new process, or else throw a RuntimeException.
3079            boolean isActivityProcess = (entryPoint == null);
3080            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3081            Process.ProcessStartResult startResult = Process.start(entryPoint,
3082                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3083                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3084
3085            if (app.isolated) {
3086                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3087            }
3088            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3089
3090            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3091                    UserHandle.getUserId(uid), startResult.pid, uid,
3092                    app.processName, hostingType,
3093                    hostingNameStr != null ? hostingNameStr : "");
3094
3095            if (app.persistent) {
3096                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3097            }
3098
3099            StringBuilder buf = mStringBuilder;
3100            buf.setLength(0);
3101            buf.append("Start proc ");
3102            buf.append(app.processName);
3103            if (!isActivityProcess) {
3104                buf.append(" [");
3105                buf.append(entryPoint);
3106                buf.append("]");
3107            }
3108            buf.append(" for ");
3109            buf.append(hostingType);
3110            if (hostingNameStr != null) {
3111                buf.append(" ");
3112                buf.append(hostingNameStr);
3113            }
3114            buf.append(": pid=");
3115            buf.append(startResult.pid);
3116            buf.append(" uid=");
3117            buf.append(uid);
3118            buf.append(" gids={");
3119            if (gids != null) {
3120                for (int gi=0; gi<gids.length; gi++) {
3121                    if (gi != 0) buf.append(", ");
3122                    buf.append(gids[gi]);
3123
3124                }
3125            }
3126            buf.append("}");
3127            if (requiredAbi != null) {
3128                buf.append(" abi=");
3129                buf.append(requiredAbi);
3130            }
3131            Slog.i(TAG, buf.toString());
3132            app.setPid(startResult.pid);
3133            app.usingWrapper = startResult.usingWrapper;
3134            app.removed = false;
3135            app.killedByAm = false;
3136            synchronized (mPidsSelfLocked) {
3137                this.mPidsSelfLocked.put(startResult.pid, app);
3138                if (isActivityProcess) {
3139                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3140                    msg.obj = app;
3141                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3142                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3143                }
3144            }
3145        } catch (RuntimeException e) {
3146            // XXX do better error recovery.
3147            app.setPid(0);
3148            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3149            if (app.isolated) {
3150                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3151            }
3152            Slog.e(TAG, "Failure starting process " + app.processName, e);
3153        }
3154    }
3155
3156    void updateUsageStats(ActivityRecord component, boolean resumed) {
3157        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3158        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3159        if (resumed) {
3160            if (mUsageStatsService != null) {
3161                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3162                        System.currentTimeMillis(),
3163                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3164            }
3165            synchronized (stats) {
3166                stats.noteActivityResumedLocked(component.app.uid);
3167            }
3168        } else {
3169            if (mUsageStatsService != null) {
3170                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3171                        System.currentTimeMillis(),
3172                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3173            }
3174            synchronized (stats) {
3175                stats.noteActivityPausedLocked(component.app.uid);
3176            }
3177        }
3178    }
3179
3180    Intent getHomeIntent() {
3181        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3182        intent.setComponent(mTopComponent);
3183        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3184            intent.addCategory(Intent.CATEGORY_HOME);
3185        }
3186        return intent;
3187    }
3188
3189    boolean startHomeActivityLocked(int userId) {
3190        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3191                && mTopAction == null) {
3192            // We are running in factory test mode, but unable to find
3193            // the factory test app, so just sit around displaying the
3194            // error message and don't try to start anything.
3195            return false;
3196        }
3197        Intent intent = getHomeIntent();
3198        ActivityInfo aInfo =
3199            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3200        if (aInfo != null) {
3201            intent.setComponent(new ComponentName(
3202                    aInfo.applicationInfo.packageName, aInfo.name));
3203            // Don't do this if the home app is currently being
3204            // instrumented.
3205            aInfo = new ActivityInfo(aInfo);
3206            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3207            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3208                    aInfo.applicationInfo.uid, true);
3209            if (app == null || app.instrumentationClass == null) {
3210                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3211                mStackSupervisor.startHomeActivity(intent, aInfo);
3212            }
3213        }
3214
3215        return true;
3216    }
3217
3218    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3219        ActivityInfo ai = null;
3220        ComponentName comp = intent.getComponent();
3221        try {
3222            if (comp != null) {
3223                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3224            } else {
3225                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3226                        intent,
3227                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3228                            flags, userId);
3229
3230                if (info != null) {
3231                    ai = info.activityInfo;
3232                }
3233            }
3234        } catch (RemoteException e) {
3235            // ignore
3236        }
3237
3238        return ai;
3239    }
3240
3241    /**
3242     * Starts the "new version setup screen" if appropriate.
3243     */
3244    void startSetupActivityLocked() {
3245        // Only do this once per boot.
3246        if (mCheckedForSetup) {
3247            return;
3248        }
3249
3250        // We will show this screen if the current one is a different
3251        // version than the last one shown, and we are not running in
3252        // low-level factory test mode.
3253        final ContentResolver resolver = mContext.getContentResolver();
3254        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3255                Settings.Global.getInt(resolver,
3256                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3257            mCheckedForSetup = true;
3258
3259            // See if we should be showing the platform update setup UI.
3260            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3261            List<ResolveInfo> ris = mContext.getPackageManager()
3262                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3263
3264            // We don't allow third party apps to replace this.
3265            ResolveInfo ri = null;
3266            for (int i=0; ris != null && i<ris.size(); i++) {
3267                if ((ris.get(i).activityInfo.applicationInfo.flags
3268                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3269                    ri = ris.get(i);
3270                    break;
3271                }
3272            }
3273
3274            if (ri != null) {
3275                String vers = ri.activityInfo.metaData != null
3276                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3277                        : null;
3278                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3279                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3280                            Intent.METADATA_SETUP_VERSION);
3281                }
3282                String lastVers = Settings.Secure.getString(
3283                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3284                if (vers != null && !vers.equals(lastVers)) {
3285                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3286                    intent.setComponent(new ComponentName(
3287                            ri.activityInfo.packageName, ri.activityInfo.name));
3288                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3289                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3290                }
3291            }
3292        }
3293    }
3294
3295    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3296        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3297    }
3298
3299    void enforceNotIsolatedCaller(String caller) {
3300        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3301            throw new SecurityException("Isolated process not allowed to call " + caller);
3302        }
3303    }
3304
3305    @Override
3306    public int getFrontActivityScreenCompatMode() {
3307        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3308        synchronized (this) {
3309            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3310        }
3311    }
3312
3313    @Override
3314    public void setFrontActivityScreenCompatMode(int mode) {
3315        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3316                "setFrontActivityScreenCompatMode");
3317        synchronized (this) {
3318            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3319        }
3320    }
3321
3322    @Override
3323    public int getPackageScreenCompatMode(String packageName) {
3324        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3325        synchronized (this) {
3326            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3327        }
3328    }
3329
3330    @Override
3331    public void setPackageScreenCompatMode(String packageName, int mode) {
3332        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3333                "setPackageScreenCompatMode");
3334        synchronized (this) {
3335            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3336        }
3337    }
3338
3339    @Override
3340    public boolean getPackageAskScreenCompat(String packageName) {
3341        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3342        synchronized (this) {
3343            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3344        }
3345    }
3346
3347    @Override
3348    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3349        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3350                "setPackageAskScreenCompat");
3351        synchronized (this) {
3352            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3353        }
3354    }
3355
3356    private void dispatchProcessesChanged() {
3357        int N;
3358        synchronized (this) {
3359            N = mPendingProcessChanges.size();
3360            if (mActiveProcessChanges.length < N) {
3361                mActiveProcessChanges = new ProcessChangeItem[N];
3362            }
3363            mPendingProcessChanges.toArray(mActiveProcessChanges);
3364            mAvailProcessChanges.addAll(mPendingProcessChanges);
3365            mPendingProcessChanges.clear();
3366            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3367        }
3368
3369        int i = mProcessObservers.beginBroadcast();
3370        while (i > 0) {
3371            i--;
3372            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3373            if (observer != null) {
3374                try {
3375                    for (int j=0; j<N; j++) {
3376                        ProcessChangeItem item = mActiveProcessChanges[j];
3377                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3378                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3379                                    + item.pid + " uid=" + item.uid + ": "
3380                                    + item.foregroundActivities);
3381                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3382                                    item.foregroundActivities);
3383                        }
3384                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3385                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3386                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3387                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3388                        }
3389                    }
3390                } catch (RemoteException e) {
3391                }
3392            }
3393        }
3394        mProcessObservers.finishBroadcast();
3395    }
3396
3397    private void dispatchProcessDied(int pid, int uid) {
3398        int i = mProcessObservers.beginBroadcast();
3399        while (i > 0) {
3400            i--;
3401            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3402            if (observer != null) {
3403                try {
3404                    observer.onProcessDied(pid, uid);
3405                } catch (RemoteException e) {
3406                }
3407            }
3408        }
3409        mProcessObservers.finishBroadcast();
3410    }
3411
3412    @Override
3413    public final int startActivity(IApplicationThread caller, String callingPackage,
3414            Intent intent, String resolvedType, IBinder resultTo,
3415            String resultWho, int requestCode, int startFlags,
3416            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3417        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3418                resultWho, requestCode,
3419                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3420    }
3421
3422    @Override
3423    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3424            Intent intent, String resolvedType, IBinder resultTo,
3425            String resultWho, int requestCode, int startFlags,
3426            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3427        enforceNotIsolatedCaller("startActivity");
3428        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3429                false, ALLOW_FULL_ONLY, "startActivity", null);
3430        // TODO: Switch to user app stacks here.
3431        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3432                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3433                null, null, options, userId, null);
3434    }
3435
3436    @Override
3437    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3438            Intent intent, String resolvedType, IBinder resultTo,
3439            String resultWho, int requestCode, int startFlags, String profileFile,
3440            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3441        enforceNotIsolatedCaller("startActivityAndWait");
3442        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3443                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3444        WaitResult res = new WaitResult();
3445        // TODO: Switch to user app stacks here.
3446        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3447                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3448                res, null, options, userId, null);
3449        return res;
3450    }
3451
3452    @Override
3453    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3454            Intent intent, String resolvedType, IBinder resultTo,
3455            String resultWho, int requestCode, int startFlags, Configuration config,
3456            Bundle options, int userId) {
3457        enforceNotIsolatedCaller("startActivityWithConfig");
3458        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3459                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3460        // TODO: Switch to user app stacks here.
3461        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3462                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3463                null, null, null, config, options, userId, null);
3464        return ret;
3465    }
3466
3467    @Override
3468    public int startActivityIntentSender(IApplicationThread caller,
3469            IntentSender intent, Intent fillInIntent, String resolvedType,
3470            IBinder resultTo, String resultWho, int requestCode,
3471            int flagsMask, int flagsValues, Bundle options) {
3472        enforceNotIsolatedCaller("startActivityIntentSender");
3473        // Refuse possible leaked file descriptors
3474        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3475            throw new IllegalArgumentException("File descriptors passed in Intent");
3476        }
3477
3478        IIntentSender sender = intent.getTarget();
3479        if (!(sender instanceof PendingIntentRecord)) {
3480            throw new IllegalArgumentException("Bad PendingIntent object");
3481        }
3482
3483        PendingIntentRecord pir = (PendingIntentRecord)sender;
3484
3485        synchronized (this) {
3486            // If this is coming from the currently resumed activity, it is
3487            // effectively saying that app switches are allowed at this point.
3488            final ActivityStack stack = getFocusedStack();
3489            if (stack.mResumedActivity != null &&
3490                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3491                mAppSwitchesAllowedTime = 0;
3492            }
3493        }
3494        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3495                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3496        return ret;
3497    }
3498
3499    @Override
3500    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3501            Intent intent, String resolvedType, IVoiceInteractionSession session,
3502            IVoiceInteractor interactor, int startFlags, String profileFile,
3503            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3504        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3505                != PackageManager.PERMISSION_GRANTED) {
3506            String msg = "Permission Denial: startVoiceActivity() from pid="
3507                    + Binder.getCallingPid()
3508                    + ", uid=" + Binder.getCallingUid()
3509                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3510            Slog.w(TAG, msg);
3511            throw new SecurityException(msg);
3512        }
3513        if (session == null || interactor == null) {
3514            throw new NullPointerException("null session or interactor");
3515        }
3516        userId = handleIncomingUser(callingPid, callingUid, userId,
3517                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3518        // TODO: Switch to user app stacks here.
3519        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3520                resolvedType, session, interactor, null, null, 0, startFlags,
3521                profileFile, profileFd, null, null, options, userId, null);
3522    }
3523
3524    @Override
3525    public boolean startNextMatchingActivity(IBinder callingActivity,
3526            Intent intent, Bundle options) {
3527        // Refuse possible leaked file descriptors
3528        if (intent != null && intent.hasFileDescriptors() == true) {
3529            throw new IllegalArgumentException("File descriptors passed in Intent");
3530        }
3531
3532        synchronized (this) {
3533            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3534            if (r == null) {
3535                ActivityOptions.abort(options);
3536                return false;
3537            }
3538            if (r.app == null || r.app.thread == null) {
3539                // The caller is not running...  d'oh!
3540                ActivityOptions.abort(options);
3541                return false;
3542            }
3543            intent = new Intent(intent);
3544            // The caller is not allowed to change the data.
3545            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3546            // And we are resetting to find the next component...
3547            intent.setComponent(null);
3548
3549            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3550
3551            ActivityInfo aInfo = null;
3552            try {
3553                List<ResolveInfo> resolves =
3554                    AppGlobals.getPackageManager().queryIntentActivities(
3555                            intent, r.resolvedType,
3556                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3557                            UserHandle.getCallingUserId());
3558
3559                // Look for the original activity in the list...
3560                final int N = resolves != null ? resolves.size() : 0;
3561                for (int i=0; i<N; i++) {
3562                    ResolveInfo rInfo = resolves.get(i);
3563                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3564                            && rInfo.activityInfo.name.equals(r.info.name)) {
3565                        // We found the current one...  the next matching is
3566                        // after it.
3567                        i++;
3568                        if (i<N) {
3569                            aInfo = resolves.get(i).activityInfo;
3570                        }
3571                        if (debug) {
3572                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3573                                    + "/" + r.info.name);
3574                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3575                                    + "/" + aInfo.name);
3576                        }
3577                        break;
3578                    }
3579                }
3580            } catch (RemoteException e) {
3581            }
3582
3583            if (aInfo == null) {
3584                // Nobody who is next!
3585                ActivityOptions.abort(options);
3586                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3587                return false;
3588            }
3589
3590            intent.setComponent(new ComponentName(
3591                    aInfo.applicationInfo.packageName, aInfo.name));
3592            intent.setFlags(intent.getFlags()&~(
3593                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3594                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3595                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3596                    Intent.FLAG_ACTIVITY_NEW_TASK));
3597
3598            // Okay now we need to start the new activity, replacing the
3599            // currently running activity.  This is a little tricky because
3600            // we want to start the new one as if the current one is finished,
3601            // but not finish the current one first so that there is no flicker.
3602            // And thus...
3603            final boolean wasFinishing = r.finishing;
3604            r.finishing = true;
3605
3606            // Propagate reply information over to the new activity.
3607            final ActivityRecord resultTo = r.resultTo;
3608            final String resultWho = r.resultWho;
3609            final int requestCode = r.requestCode;
3610            r.resultTo = null;
3611            if (resultTo != null) {
3612                resultTo.removeResultsLocked(r, resultWho, requestCode);
3613            }
3614
3615            final long origId = Binder.clearCallingIdentity();
3616            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3617                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3618                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3619                    options, false, null, null);
3620            Binder.restoreCallingIdentity(origId);
3621
3622            r.finishing = wasFinishing;
3623            if (res != ActivityManager.START_SUCCESS) {
3624                return false;
3625            }
3626            return true;
3627        }
3628    }
3629
3630    @Override
3631    public final int startActivityFromRecents(int taskId, Bundle options) {
3632        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3633            String msg = "Permission Denial: startActivityFromRecents called without " +
3634                    START_TASKS_FROM_RECENTS;
3635            Slog.w(TAG, msg);
3636            throw new SecurityException(msg);
3637        }
3638        final int callingUid;
3639        final String callingPackage;
3640        final Intent intent;
3641        final int userId;
3642        synchronized (this) {
3643            final TaskRecord task = recentTaskForIdLocked(taskId);
3644            if (task == null) {
3645                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3646            }
3647            callingUid = task.mCallingUid;
3648            callingPackage = task.mCallingPackage;
3649            intent = task.intent;
3650            userId = task.userId;
3651        }
3652        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3653                options, userId, null);
3654    }
3655
3656    final int startActivityInPackage(int uid, String callingPackage,
3657            Intent intent, String resolvedType, IBinder resultTo,
3658            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3659                    IActivityContainer container) {
3660
3661        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3662                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3663
3664        // TODO: Switch to user app stacks here.
3665        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3666                null, null, resultTo, resultWho, requestCode, startFlags,
3667                null, null, null, null, options, userId, container);
3668        return ret;
3669    }
3670
3671    @Override
3672    public final int startActivities(IApplicationThread caller, String callingPackage,
3673            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3674            int userId) {
3675        enforceNotIsolatedCaller("startActivities");
3676        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3677                false, ALLOW_FULL_ONLY, "startActivity", null);
3678        // TODO: Switch to user app stacks here.
3679        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3680                resolvedTypes, resultTo, options, userId);
3681        return ret;
3682    }
3683
3684    final int startActivitiesInPackage(int uid, String callingPackage,
3685            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3686            Bundle options, int userId) {
3687
3688        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3689                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3690        // TODO: Switch to user app stacks here.
3691        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3692                resultTo, options, userId);
3693        return ret;
3694    }
3695
3696    //explicitly remove thd old information in mRecentTasks when removing existing user.
3697    private void removeRecentTasksForUserLocked(int userId) {
3698        if(userId <= 0) {
3699            Slog.i(TAG, "Can't remove recent task on user " + userId);
3700            return;
3701        }
3702
3703        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3704            TaskRecord tr = mRecentTasks.get(i);
3705            if (tr.userId == userId) {
3706                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3707                        + " when finishing user" + userId);
3708                tr.disposeThumbnail();
3709                mRecentTasks.remove(i);
3710            }
3711        }
3712
3713        // Remove tasks from persistent storage.
3714        mTaskPersister.wakeup(null, true);
3715    }
3716
3717    final void addRecentTaskLocked(TaskRecord task) {
3718        int N = mRecentTasks.size();
3719        // Quick case: check if the top-most recent task is the same.
3720        if (N > 0 && mRecentTasks.get(0) == task) {
3721            return;
3722        }
3723        // Another quick case: never add voice sessions.
3724        if (task.voiceSession != null) {
3725            return;
3726        }
3727        // Remove any existing entries that are the same kind of task.
3728        final Intent intent = task.intent;
3729        final boolean document = intent != null && intent.isDocument();
3730        final ComponentName comp = intent.getComponent();
3731
3732        int maxRecents = task.maxRecents - 1;
3733        for (int i=0; i<N; i++) {
3734            final TaskRecord tr = mRecentTasks.get(i);
3735            if (task != tr) {
3736                if (task.userId != tr.userId) {
3737                    continue;
3738                }
3739                if (i > MAX_RECENT_BITMAPS) {
3740                    tr.freeLastThumbnail();
3741                }
3742                final Intent trIntent = tr.intent;
3743                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3744                    (intent == null || !intent.filterEquals(trIntent))) {
3745                    continue;
3746                }
3747                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3748                if (document && trIsDocument) {
3749                    // These are the same document activity (not necessarily the same doc).
3750                    if (maxRecents > 0) {
3751                        --maxRecents;
3752                        continue;
3753                    }
3754                    // Hit the maximum number of documents for this task. Fall through
3755                    // and remove this document from recents.
3756                } else if (document || trIsDocument) {
3757                    // Only one of these is a document. Not the droid we're looking for.
3758                    continue;
3759                }
3760            }
3761
3762            // Either task and tr are the same or, their affinities match or their intents match
3763            // and neither of them is a document, or they are documents using the same activity
3764            // and their maxRecents has been reached.
3765            tr.disposeThumbnail();
3766            mRecentTasks.remove(i);
3767            if (task != tr) {
3768                tr.closeRecentsChain();
3769            }
3770            i--;
3771            N--;
3772            if (task.intent == null) {
3773                // If the new recent task we are adding is not fully
3774                // specified, then replace it with the existing recent task.
3775                task = tr;
3776            }
3777            notifyTaskPersisterLocked(tr, false);
3778        }
3779        if (N >= MAX_RECENT_TASKS) {
3780            final TaskRecord tr = mRecentTasks.remove(N - 1);
3781            tr.disposeThumbnail();
3782            tr.closeRecentsChain();
3783        }
3784        mRecentTasks.add(0, task);
3785    }
3786
3787    @Override
3788    public void reportActivityFullyDrawn(IBinder token) {
3789        synchronized (this) {
3790            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3791            if (r == null) {
3792                return;
3793            }
3794            r.reportFullyDrawnLocked();
3795        }
3796    }
3797
3798    @Override
3799    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3800        synchronized (this) {
3801            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3802            if (r == null) {
3803                return;
3804            }
3805            final long origId = Binder.clearCallingIdentity();
3806            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3807            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3808                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3809            if (config != null) {
3810                r.frozenBeforeDestroy = true;
3811                if (!updateConfigurationLocked(config, r, false, false)) {
3812                    mStackSupervisor.resumeTopActivitiesLocked();
3813                }
3814            }
3815            Binder.restoreCallingIdentity(origId);
3816        }
3817    }
3818
3819    @Override
3820    public int getRequestedOrientation(IBinder token) {
3821        synchronized (this) {
3822            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3823            if (r == null) {
3824                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3825            }
3826            return mWindowManager.getAppOrientation(r.appToken);
3827        }
3828    }
3829
3830    /**
3831     * This is the internal entry point for handling Activity.finish().
3832     *
3833     * @param token The Binder token referencing the Activity we want to finish.
3834     * @param resultCode Result code, if any, from this Activity.
3835     * @param resultData Result data (Intent), if any, from this Activity.
3836     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3837     *            the root Activity in the task.
3838     *
3839     * @return Returns true if the activity successfully finished, or false if it is still running.
3840     */
3841    @Override
3842    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3843            boolean finishTask) {
3844        // Refuse possible leaked file descriptors
3845        if (resultData != null && resultData.hasFileDescriptors() == true) {
3846            throw new IllegalArgumentException("File descriptors passed in Intent");
3847        }
3848
3849        synchronized(this) {
3850            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3851            if (r == null) {
3852                return true;
3853            }
3854            // Keep track of the root activity of the task before we finish it
3855            TaskRecord tr = r.task;
3856            ActivityRecord rootR = tr.getRootActivity();
3857            // Do not allow task to finish in Lock Task mode.
3858            if (tr == mStackSupervisor.mLockTaskModeTask) {
3859                if (rootR == r) {
3860                    mStackSupervisor.showLockTaskToast();
3861                    return false;
3862                }
3863            }
3864            if (mController != null) {
3865                // Find the first activity that is not finishing.
3866                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3867                if (next != null) {
3868                    // ask watcher if this is allowed
3869                    boolean resumeOK = true;
3870                    try {
3871                        resumeOK = mController.activityResuming(next.packageName);
3872                    } catch (RemoteException e) {
3873                        mController = null;
3874                        Watchdog.getInstance().setActivityController(null);
3875                    }
3876
3877                    if (!resumeOK) {
3878                        return false;
3879                    }
3880                }
3881            }
3882            final long origId = Binder.clearCallingIdentity();
3883            try {
3884                boolean res;
3885                if (finishTask && r == rootR) {
3886                    // If requested, remove the task that is associated to this activity only if it
3887                    // was the root activity in the task.  The result code and data is ignored because
3888                    // we don't support returning them across task boundaries.
3889                    res = removeTaskByIdLocked(tr.taskId, 0);
3890                } else {
3891                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3892                            resultData, "app-request", true);
3893                }
3894                return res;
3895            } finally {
3896                Binder.restoreCallingIdentity(origId);
3897            }
3898        }
3899    }
3900
3901    @Override
3902    public final void finishHeavyWeightApp() {
3903        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3904                != PackageManager.PERMISSION_GRANTED) {
3905            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3906                    + Binder.getCallingPid()
3907                    + ", uid=" + Binder.getCallingUid()
3908                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3909            Slog.w(TAG, msg);
3910            throw new SecurityException(msg);
3911        }
3912
3913        synchronized(this) {
3914            if (mHeavyWeightProcess == null) {
3915                return;
3916            }
3917
3918            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3919                    mHeavyWeightProcess.activities);
3920            for (int i=0; i<activities.size(); i++) {
3921                ActivityRecord r = activities.get(i);
3922                if (!r.finishing) {
3923                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3924                            null, "finish-heavy", true);
3925                }
3926            }
3927
3928            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3929                    mHeavyWeightProcess.userId, 0));
3930            mHeavyWeightProcess = null;
3931        }
3932    }
3933
3934    @Override
3935    public void crashApplication(int uid, int initialPid, String packageName,
3936            String message) {
3937        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3938                != PackageManager.PERMISSION_GRANTED) {
3939            String msg = "Permission Denial: crashApplication() from pid="
3940                    + Binder.getCallingPid()
3941                    + ", uid=" + Binder.getCallingUid()
3942                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3943            Slog.w(TAG, msg);
3944            throw new SecurityException(msg);
3945        }
3946
3947        synchronized(this) {
3948            ProcessRecord proc = null;
3949
3950            // Figure out which process to kill.  We don't trust that initialPid
3951            // still has any relation to current pids, so must scan through the
3952            // list.
3953            synchronized (mPidsSelfLocked) {
3954                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3955                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3956                    if (p.uid != uid) {
3957                        continue;
3958                    }
3959                    if (p.pid == initialPid) {
3960                        proc = p;
3961                        break;
3962                    }
3963                    if (p.pkgList.containsKey(packageName)) {
3964                        proc = p;
3965                    }
3966                }
3967            }
3968
3969            if (proc == null) {
3970                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3971                        + " initialPid=" + initialPid
3972                        + " packageName=" + packageName);
3973                return;
3974            }
3975
3976            if (proc.thread != null) {
3977                if (proc.pid == Process.myPid()) {
3978                    Log.w(TAG, "crashApplication: trying to crash self!");
3979                    return;
3980                }
3981                long ident = Binder.clearCallingIdentity();
3982                try {
3983                    proc.thread.scheduleCrash(message);
3984                } catch (RemoteException e) {
3985                }
3986                Binder.restoreCallingIdentity(ident);
3987            }
3988        }
3989    }
3990
3991    @Override
3992    public final void finishSubActivity(IBinder token, String resultWho,
3993            int requestCode) {
3994        synchronized(this) {
3995            final long origId = Binder.clearCallingIdentity();
3996            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3997            if (r != null) {
3998                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3999            }
4000            Binder.restoreCallingIdentity(origId);
4001        }
4002    }
4003
4004    @Override
4005    public boolean finishActivityAffinity(IBinder token) {
4006        synchronized(this) {
4007            final long origId = Binder.clearCallingIdentity();
4008            try {
4009                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4010
4011                ActivityRecord rootR = r.task.getRootActivity();
4012                // Do not allow task to finish in Lock Task mode.
4013                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4014                    if (rootR == r) {
4015                        mStackSupervisor.showLockTaskToast();
4016                        return false;
4017                    }
4018                }
4019                boolean res = false;
4020                if (r != null) {
4021                    res = r.task.stack.finishActivityAffinityLocked(r);
4022                }
4023                return res;
4024            } finally {
4025                Binder.restoreCallingIdentity(origId);
4026            }
4027        }
4028    }
4029
4030    @Override
4031    public void finishVoiceTask(IVoiceInteractionSession session) {
4032        synchronized(this) {
4033            final long origId = Binder.clearCallingIdentity();
4034            try {
4035                mStackSupervisor.finishVoiceTask(session);
4036            } finally {
4037                Binder.restoreCallingIdentity(origId);
4038            }
4039        }
4040
4041    }
4042
4043    @Override
4044    public boolean willActivityBeVisible(IBinder token) {
4045        synchronized(this) {
4046            ActivityStack stack = ActivityRecord.getStackLocked(token);
4047            if (stack != null) {
4048                return stack.willActivityBeVisibleLocked(token);
4049            }
4050            return false;
4051        }
4052    }
4053
4054    @Override
4055    public void overridePendingTransition(IBinder token, String packageName,
4056            int enterAnim, int exitAnim) {
4057        synchronized(this) {
4058            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4059            if (self == null) {
4060                return;
4061            }
4062
4063            final long origId = Binder.clearCallingIdentity();
4064
4065            if (self.state == ActivityState.RESUMED
4066                    || self.state == ActivityState.PAUSING) {
4067                mWindowManager.overridePendingAppTransition(packageName,
4068                        enterAnim, exitAnim, null);
4069            }
4070
4071            Binder.restoreCallingIdentity(origId);
4072        }
4073    }
4074
4075    /**
4076     * Main function for removing an existing process from the activity manager
4077     * as a result of that process going away.  Clears out all connections
4078     * to the process.
4079     */
4080    private final void handleAppDiedLocked(ProcessRecord app,
4081            boolean restarting, boolean allowRestart) {
4082        int pid = app.pid;
4083        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4084        if (!restarting) {
4085            removeLruProcessLocked(app);
4086            if (pid > 0) {
4087                ProcessList.remove(pid);
4088            }
4089        }
4090
4091        if (mProfileProc == app) {
4092            clearProfilerLocked();
4093        }
4094
4095        // Remove this application's activities from active lists.
4096        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4097
4098        app.activities.clear();
4099
4100        if (app.instrumentationClass != null) {
4101            Slog.w(TAG, "Crash of app " + app.processName
4102                  + " running instrumentation " + app.instrumentationClass);
4103            Bundle info = new Bundle();
4104            info.putString("shortMsg", "Process crashed.");
4105            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4106        }
4107
4108        if (!restarting) {
4109            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4110                // If there was nothing to resume, and we are not already
4111                // restarting this process, but there is a visible activity that
4112                // is hosted by the process...  then make sure all visible
4113                // activities are running, taking care of restarting this
4114                // process.
4115                if (hasVisibleActivities) {
4116                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4117                }
4118            }
4119        }
4120    }
4121
4122    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4123        IBinder threadBinder = thread.asBinder();
4124        // Find the application record.
4125        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4126            ProcessRecord rec = mLruProcesses.get(i);
4127            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4128                return i;
4129            }
4130        }
4131        return -1;
4132    }
4133
4134    final ProcessRecord getRecordForAppLocked(
4135            IApplicationThread thread) {
4136        if (thread == null) {
4137            return null;
4138        }
4139
4140        int appIndex = getLRURecordIndexForAppLocked(thread);
4141        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4142    }
4143
4144    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4145        // If there are no longer any background processes running,
4146        // and the app that died was not running instrumentation,
4147        // then tell everyone we are now low on memory.
4148        boolean haveBg = false;
4149        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4150            ProcessRecord rec = mLruProcesses.get(i);
4151            if (rec.thread != null
4152                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4153                haveBg = true;
4154                break;
4155            }
4156        }
4157
4158        if (!haveBg) {
4159            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4160            if (doReport) {
4161                long now = SystemClock.uptimeMillis();
4162                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4163                    doReport = false;
4164                } else {
4165                    mLastMemUsageReportTime = now;
4166                }
4167            }
4168            final ArrayList<ProcessMemInfo> memInfos
4169                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4170            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4171            long now = SystemClock.uptimeMillis();
4172            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4173                ProcessRecord rec = mLruProcesses.get(i);
4174                if (rec == dyingProc || rec.thread == null) {
4175                    continue;
4176                }
4177                if (doReport) {
4178                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4179                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4180                }
4181                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4182                    // The low memory report is overriding any current
4183                    // state for a GC request.  Make sure to do
4184                    // heavy/important/visible/foreground processes first.
4185                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4186                        rec.lastRequestedGc = 0;
4187                    } else {
4188                        rec.lastRequestedGc = rec.lastLowMemory;
4189                    }
4190                    rec.reportLowMemory = true;
4191                    rec.lastLowMemory = now;
4192                    mProcessesToGc.remove(rec);
4193                    addProcessToGcListLocked(rec);
4194                }
4195            }
4196            if (doReport) {
4197                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4198                mHandler.sendMessage(msg);
4199            }
4200            scheduleAppGcsLocked();
4201        }
4202    }
4203
4204    final void appDiedLocked(ProcessRecord app, int pid,
4205            IApplicationThread thread) {
4206
4207        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4208        synchronized (stats) {
4209            stats.noteProcessDiedLocked(app.info.uid, pid);
4210        }
4211
4212        Process.killProcessGroup(app.info.uid, pid);
4213
4214        // Clean up already done if the process has been re-started.
4215        if (app.pid == pid && app.thread != null &&
4216                app.thread.asBinder() == thread.asBinder()) {
4217            boolean doLowMem = app.instrumentationClass == null;
4218            boolean doOomAdj = doLowMem;
4219            if (!app.killedByAm) {
4220                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4221                        + ") has died.");
4222                mAllowLowerMemLevel = true;
4223            } else {
4224                // Note that we always want to do oom adj to update our state with the
4225                // new number of procs.
4226                mAllowLowerMemLevel = false;
4227                doLowMem = false;
4228            }
4229            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4230            if (DEBUG_CLEANUP) Slog.v(
4231                TAG, "Dying app: " + app + ", pid: " + pid
4232                + ", thread: " + thread.asBinder());
4233            handleAppDiedLocked(app, false, true);
4234
4235            if (doOomAdj) {
4236                updateOomAdjLocked();
4237            }
4238            if (doLowMem) {
4239                doLowMemReportIfNeededLocked(app);
4240            }
4241        } else if (app.pid != pid) {
4242            // A new process has already been started.
4243            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4244                    + ") has died and restarted (pid " + app.pid + ").");
4245            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4246        } else if (DEBUG_PROCESSES) {
4247            Slog.d(TAG, "Received spurious death notification for thread "
4248                    + thread.asBinder());
4249        }
4250    }
4251
4252    /**
4253     * If a stack trace dump file is configured, dump process stack traces.
4254     * @param clearTraces causes the dump file to be erased prior to the new
4255     *    traces being written, if true; when false, the new traces will be
4256     *    appended to any existing file content.
4257     * @param firstPids of dalvik VM processes to dump stack traces for first
4258     * @param lastPids of dalvik VM processes to dump stack traces for last
4259     * @param nativeProcs optional list of native process names to dump stack crawls
4260     * @return file containing stack traces, or null if no dump file is configured
4261     */
4262    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4263            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4264        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4265        if (tracesPath == null || tracesPath.length() == 0) {
4266            return null;
4267        }
4268
4269        File tracesFile = new File(tracesPath);
4270        try {
4271            File tracesDir = tracesFile.getParentFile();
4272            if (!tracesDir.exists()) {
4273                tracesFile.mkdirs();
4274                if (!SELinux.restorecon(tracesDir)) {
4275                    return null;
4276                }
4277            }
4278            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4279
4280            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4281            tracesFile.createNewFile();
4282            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4283        } catch (IOException e) {
4284            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4285            return null;
4286        }
4287
4288        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4289        return tracesFile;
4290    }
4291
4292    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4293            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4294        // Use a FileObserver to detect when traces finish writing.
4295        // The order of traces is considered important to maintain for legibility.
4296        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4297            @Override
4298            public synchronized void onEvent(int event, String path) { notify(); }
4299        };
4300
4301        try {
4302            observer.startWatching();
4303
4304            // First collect all of the stacks of the most important pids.
4305            if (firstPids != null) {
4306                try {
4307                    int num = firstPids.size();
4308                    for (int i = 0; i < num; i++) {
4309                        synchronized (observer) {
4310                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4311                            observer.wait(200);  // Wait for write-close, give up after 200msec
4312                        }
4313                    }
4314                } catch (InterruptedException e) {
4315                    Log.wtf(TAG, e);
4316                }
4317            }
4318
4319            // Next collect the stacks of the native pids
4320            if (nativeProcs != null) {
4321                int[] pids = Process.getPidsForCommands(nativeProcs);
4322                if (pids != null) {
4323                    for (int pid : pids) {
4324                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4325                    }
4326                }
4327            }
4328
4329            // Lastly, measure CPU usage.
4330            if (processCpuTracker != null) {
4331                processCpuTracker.init();
4332                System.gc();
4333                processCpuTracker.update();
4334                try {
4335                    synchronized (processCpuTracker) {
4336                        processCpuTracker.wait(500); // measure over 1/2 second.
4337                    }
4338                } catch (InterruptedException e) {
4339                }
4340                processCpuTracker.update();
4341
4342                // We'll take the stack crawls of just the top apps using CPU.
4343                final int N = processCpuTracker.countWorkingStats();
4344                int numProcs = 0;
4345                for (int i=0; i<N && numProcs<5; i++) {
4346                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4347                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4348                        numProcs++;
4349                        try {
4350                            synchronized (observer) {
4351                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4352                                observer.wait(200);  // Wait for write-close, give up after 200msec
4353                            }
4354                        } catch (InterruptedException e) {
4355                            Log.wtf(TAG, e);
4356                        }
4357
4358                    }
4359                }
4360            }
4361        } finally {
4362            observer.stopWatching();
4363        }
4364    }
4365
4366    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4367        if (true || IS_USER_BUILD) {
4368            return;
4369        }
4370        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4371        if (tracesPath == null || tracesPath.length() == 0) {
4372            return;
4373        }
4374
4375        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4376        StrictMode.allowThreadDiskWrites();
4377        try {
4378            final File tracesFile = new File(tracesPath);
4379            final File tracesDir = tracesFile.getParentFile();
4380            final File tracesTmp = new File(tracesDir, "__tmp__");
4381            try {
4382                if (!tracesDir.exists()) {
4383                    tracesFile.mkdirs();
4384                    if (!SELinux.restorecon(tracesDir.getPath())) {
4385                        return;
4386                    }
4387                }
4388                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4389
4390                if (tracesFile.exists()) {
4391                    tracesTmp.delete();
4392                    tracesFile.renameTo(tracesTmp);
4393                }
4394                StringBuilder sb = new StringBuilder();
4395                Time tobj = new Time();
4396                tobj.set(System.currentTimeMillis());
4397                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4398                sb.append(": ");
4399                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4400                sb.append(" since ");
4401                sb.append(msg);
4402                FileOutputStream fos = new FileOutputStream(tracesFile);
4403                fos.write(sb.toString().getBytes());
4404                if (app == null) {
4405                    fos.write("\n*** No application process!".getBytes());
4406                }
4407                fos.close();
4408                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4409            } catch (IOException e) {
4410                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4411                return;
4412            }
4413
4414            if (app != null) {
4415                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4416                firstPids.add(app.pid);
4417                dumpStackTraces(tracesPath, firstPids, null, null, null);
4418            }
4419
4420            File lastTracesFile = null;
4421            File curTracesFile = null;
4422            for (int i=9; i>=0; i--) {
4423                String name = String.format(Locale.US, "slow%02d.txt", i);
4424                curTracesFile = new File(tracesDir, name);
4425                if (curTracesFile.exists()) {
4426                    if (lastTracesFile != null) {
4427                        curTracesFile.renameTo(lastTracesFile);
4428                    } else {
4429                        curTracesFile.delete();
4430                    }
4431                }
4432                lastTracesFile = curTracesFile;
4433            }
4434            tracesFile.renameTo(curTracesFile);
4435            if (tracesTmp.exists()) {
4436                tracesTmp.renameTo(tracesFile);
4437            }
4438        } finally {
4439            StrictMode.setThreadPolicy(oldPolicy);
4440        }
4441    }
4442
4443    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4444            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4445        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4446        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4447
4448        if (mController != null) {
4449            try {
4450                // 0 == continue, -1 = kill process immediately
4451                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4452                if (res < 0 && app.pid != MY_PID) {
4453                    Process.killProcess(app.pid);
4454                    Process.killProcessGroup(app.info.uid, app.pid);
4455                }
4456            } catch (RemoteException e) {
4457                mController = null;
4458                Watchdog.getInstance().setActivityController(null);
4459            }
4460        }
4461
4462        long anrTime = SystemClock.uptimeMillis();
4463        if (MONITOR_CPU_USAGE) {
4464            updateCpuStatsNow();
4465        }
4466
4467        synchronized (this) {
4468            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4469            if (mShuttingDown) {
4470                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4471                return;
4472            } else if (app.notResponding) {
4473                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4474                return;
4475            } else if (app.crashing) {
4476                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4477                return;
4478            }
4479
4480            // In case we come through here for the same app before completing
4481            // this one, mark as anring now so we will bail out.
4482            app.notResponding = true;
4483
4484            // Log the ANR to the event log.
4485            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4486                    app.processName, app.info.flags, annotation);
4487
4488            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4489            firstPids.add(app.pid);
4490
4491            int parentPid = app.pid;
4492            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4493            if (parentPid != app.pid) firstPids.add(parentPid);
4494
4495            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4496
4497            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4498                ProcessRecord r = mLruProcesses.get(i);
4499                if (r != null && r.thread != null) {
4500                    int pid = r.pid;
4501                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4502                        if (r.persistent) {
4503                            firstPids.add(pid);
4504                        } else {
4505                            lastPids.put(pid, Boolean.TRUE);
4506                        }
4507                    }
4508                }
4509            }
4510        }
4511
4512        // Log the ANR to the main log.
4513        StringBuilder info = new StringBuilder();
4514        info.setLength(0);
4515        info.append("ANR in ").append(app.processName);
4516        if (activity != null && activity.shortComponentName != null) {
4517            info.append(" (").append(activity.shortComponentName).append(")");
4518        }
4519        info.append("\n");
4520        info.append("PID: ").append(app.pid).append("\n");
4521        if (annotation != null) {
4522            info.append("Reason: ").append(annotation).append("\n");
4523        }
4524        if (parent != null && parent != activity) {
4525            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4526        }
4527
4528        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4529
4530        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4531                NATIVE_STACKS_OF_INTEREST);
4532
4533        String cpuInfo = null;
4534        if (MONITOR_CPU_USAGE) {
4535            updateCpuStatsNow();
4536            synchronized (mProcessCpuThread) {
4537                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4538            }
4539            info.append(processCpuTracker.printCurrentLoad());
4540            info.append(cpuInfo);
4541        }
4542
4543        info.append(processCpuTracker.printCurrentState(anrTime));
4544
4545        Slog.e(TAG, info.toString());
4546        if (tracesFile == null) {
4547            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4548            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4549        }
4550
4551        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4552                cpuInfo, tracesFile, null);
4553
4554        if (mController != null) {
4555            try {
4556                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4557                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4558                if (res != 0) {
4559                    if (res < 0 && app.pid != MY_PID) {
4560                        Process.killProcess(app.pid);
4561                        Process.killProcessGroup(app.info.uid, app.pid);
4562                    } else {
4563                        synchronized (this) {
4564                            mServices.scheduleServiceTimeoutLocked(app);
4565                        }
4566                    }
4567                    return;
4568                }
4569            } catch (RemoteException e) {
4570                mController = null;
4571                Watchdog.getInstance().setActivityController(null);
4572            }
4573        }
4574
4575        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4576        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4577                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4578
4579        synchronized (this) {
4580            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4581                killUnneededProcessLocked(app, "background ANR");
4582                return;
4583            }
4584
4585            // Set the app's notResponding state, and look up the errorReportReceiver
4586            makeAppNotRespondingLocked(app,
4587                    activity != null ? activity.shortComponentName : null,
4588                    annotation != null ? "ANR " + annotation : "ANR",
4589                    info.toString());
4590
4591            // Bring up the infamous App Not Responding dialog
4592            Message msg = Message.obtain();
4593            HashMap<String, Object> map = new HashMap<String, Object>();
4594            msg.what = SHOW_NOT_RESPONDING_MSG;
4595            msg.obj = map;
4596            msg.arg1 = aboveSystem ? 1 : 0;
4597            map.put("app", app);
4598            if (activity != null) {
4599                map.put("activity", activity);
4600            }
4601
4602            mHandler.sendMessage(msg);
4603        }
4604    }
4605
4606    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4607        if (!mLaunchWarningShown) {
4608            mLaunchWarningShown = true;
4609            mHandler.post(new Runnable() {
4610                @Override
4611                public void run() {
4612                    synchronized (ActivityManagerService.this) {
4613                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4614                        d.show();
4615                        mHandler.postDelayed(new Runnable() {
4616                            @Override
4617                            public void run() {
4618                                synchronized (ActivityManagerService.this) {
4619                                    d.dismiss();
4620                                    mLaunchWarningShown = false;
4621                                }
4622                            }
4623                        }, 4000);
4624                    }
4625                }
4626            });
4627        }
4628    }
4629
4630    @Override
4631    public boolean clearApplicationUserData(final String packageName,
4632            final IPackageDataObserver observer, int userId) {
4633        enforceNotIsolatedCaller("clearApplicationUserData");
4634        int uid = Binder.getCallingUid();
4635        int pid = Binder.getCallingPid();
4636        userId = handleIncomingUser(pid, uid,
4637                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4638        long callingId = Binder.clearCallingIdentity();
4639        try {
4640            IPackageManager pm = AppGlobals.getPackageManager();
4641            int pkgUid = -1;
4642            synchronized(this) {
4643                try {
4644                    pkgUid = pm.getPackageUid(packageName, userId);
4645                } catch (RemoteException e) {
4646                }
4647                if (pkgUid == -1) {
4648                    Slog.w(TAG, "Invalid packageName: " + packageName);
4649                    if (observer != null) {
4650                        try {
4651                            observer.onRemoveCompleted(packageName, false);
4652                        } catch (RemoteException e) {
4653                            Slog.i(TAG, "Observer no longer exists.");
4654                        }
4655                    }
4656                    return false;
4657                }
4658                if (uid == pkgUid || checkComponentPermission(
4659                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4660                        pid, uid, -1, true)
4661                        == PackageManager.PERMISSION_GRANTED) {
4662                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4663                } else {
4664                    throw new SecurityException("PID " + pid + " does not have permission "
4665                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4666                                    + " of package " + packageName);
4667                }
4668            }
4669
4670            try {
4671                // Clear application user data
4672                pm.clearApplicationUserData(packageName, observer, userId);
4673
4674                // Remove all permissions granted from/to this package
4675                removeUriPermissionsForPackageLocked(packageName, userId, true);
4676
4677                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4678                        Uri.fromParts("package", packageName, null));
4679                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4680                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4681                        null, null, 0, null, null, null, false, false, userId);
4682            } catch (RemoteException e) {
4683            }
4684        } finally {
4685            Binder.restoreCallingIdentity(callingId);
4686        }
4687        return true;
4688    }
4689
4690    @Override
4691    public void killBackgroundProcesses(final String packageName, int userId) {
4692        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4693                != PackageManager.PERMISSION_GRANTED &&
4694                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4695                        != PackageManager.PERMISSION_GRANTED) {
4696            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4697                    + Binder.getCallingPid()
4698                    + ", uid=" + Binder.getCallingUid()
4699                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4700            Slog.w(TAG, msg);
4701            throw new SecurityException(msg);
4702        }
4703
4704        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4705                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4706        long callingId = Binder.clearCallingIdentity();
4707        try {
4708            IPackageManager pm = AppGlobals.getPackageManager();
4709            synchronized(this) {
4710                int appId = -1;
4711                try {
4712                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4713                } catch (RemoteException e) {
4714                }
4715                if (appId == -1) {
4716                    Slog.w(TAG, "Invalid packageName: " + packageName);
4717                    return;
4718                }
4719                killPackageProcessesLocked(packageName, appId, userId,
4720                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4721            }
4722        } finally {
4723            Binder.restoreCallingIdentity(callingId);
4724        }
4725    }
4726
4727    @Override
4728    public void killAllBackgroundProcesses() {
4729        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4730                != PackageManager.PERMISSION_GRANTED) {
4731            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4732                    + Binder.getCallingPid()
4733                    + ", uid=" + Binder.getCallingUid()
4734                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4735            Slog.w(TAG, msg);
4736            throw new SecurityException(msg);
4737        }
4738
4739        long callingId = Binder.clearCallingIdentity();
4740        try {
4741            synchronized(this) {
4742                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4743                final int NP = mProcessNames.getMap().size();
4744                for (int ip=0; ip<NP; ip++) {
4745                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4746                    final int NA = apps.size();
4747                    for (int ia=0; ia<NA; ia++) {
4748                        ProcessRecord app = apps.valueAt(ia);
4749                        if (app.persistent) {
4750                            // we don't kill persistent processes
4751                            continue;
4752                        }
4753                        if (app.removed) {
4754                            procs.add(app);
4755                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4756                            app.removed = true;
4757                            procs.add(app);
4758                        }
4759                    }
4760                }
4761
4762                int N = procs.size();
4763                for (int i=0; i<N; i++) {
4764                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4765                }
4766                mAllowLowerMemLevel = true;
4767                updateOomAdjLocked();
4768                doLowMemReportIfNeededLocked(null);
4769            }
4770        } finally {
4771            Binder.restoreCallingIdentity(callingId);
4772        }
4773    }
4774
4775    @Override
4776    public void forceStopPackage(final String packageName, int userId) {
4777        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4778                != PackageManager.PERMISSION_GRANTED) {
4779            String msg = "Permission Denial: forceStopPackage() from pid="
4780                    + Binder.getCallingPid()
4781                    + ", uid=" + Binder.getCallingUid()
4782                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4783            Slog.w(TAG, msg);
4784            throw new SecurityException(msg);
4785        }
4786        final int callingPid = Binder.getCallingPid();
4787        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4788                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4789        long callingId = Binder.clearCallingIdentity();
4790        try {
4791            IPackageManager pm = AppGlobals.getPackageManager();
4792            synchronized(this) {
4793                int[] users = userId == UserHandle.USER_ALL
4794                        ? getUsersLocked() : new int[] { userId };
4795                for (int user : users) {
4796                    int pkgUid = -1;
4797                    try {
4798                        pkgUid = pm.getPackageUid(packageName, user);
4799                    } catch (RemoteException e) {
4800                    }
4801                    if (pkgUid == -1) {
4802                        Slog.w(TAG, "Invalid packageName: " + packageName);
4803                        continue;
4804                    }
4805                    try {
4806                        pm.setPackageStoppedState(packageName, true, user);
4807                    } catch (RemoteException e) {
4808                    } catch (IllegalArgumentException e) {
4809                        Slog.w(TAG, "Failed trying to unstop package "
4810                                + packageName + ": " + e);
4811                    }
4812                    if (isUserRunningLocked(user, false)) {
4813                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4814                    }
4815                }
4816            }
4817        } finally {
4818            Binder.restoreCallingIdentity(callingId);
4819        }
4820    }
4821
4822    @Override
4823    public void addPackageDependency(String packageName) {
4824        synchronized (this) {
4825            int callingPid = Binder.getCallingPid();
4826            if (callingPid == Process.myPid()) {
4827                //  Yeah, um, no.
4828                Slog.w(TAG, "Can't addPackageDependency on system process");
4829                return;
4830            }
4831            ProcessRecord proc;
4832            synchronized (mPidsSelfLocked) {
4833                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4834            }
4835            if (proc != null) {
4836                if (proc.pkgDeps == null) {
4837                    proc.pkgDeps = new ArraySet<String>(1);
4838                }
4839                proc.pkgDeps.add(packageName);
4840            }
4841        }
4842    }
4843
4844    /*
4845     * The pkg name and app id have to be specified.
4846     */
4847    @Override
4848    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4849        if (pkg == null) {
4850            return;
4851        }
4852        // Make sure the uid is valid.
4853        if (appid < 0) {
4854            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4855            return;
4856        }
4857        int callerUid = Binder.getCallingUid();
4858        // Only the system server can kill an application
4859        if (callerUid == Process.SYSTEM_UID) {
4860            // Post an aysnc message to kill the application
4861            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4862            msg.arg1 = appid;
4863            msg.arg2 = 0;
4864            Bundle bundle = new Bundle();
4865            bundle.putString("pkg", pkg);
4866            bundle.putString("reason", reason);
4867            msg.obj = bundle;
4868            mHandler.sendMessage(msg);
4869        } else {
4870            throw new SecurityException(callerUid + " cannot kill pkg: " +
4871                    pkg);
4872        }
4873    }
4874
4875    @Override
4876    public void closeSystemDialogs(String reason) {
4877        enforceNotIsolatedCaller("closeSystemDialogs");
4878
4879        final int pid = Binder.getCallingPid();
4880        final int uid = Binder.getCallingUid();
4881        final long origId = Binder.clearCallingIdentity();
4882        try {
4883            synchronized (this) {
4884                // Only allow this from foreground processes, so that background
4885                // applications can't abuse it to prevent system UI from being shown.
4886                if (uid >= Process.FIRST_APPLICATION_UID) {
4887                    ProcessRecord proc;
4888                    synchronized (mPidsSelfLocked) {
4889                        proc = mPidsSelfLocked.get(pid);
4890                    }
4891                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4892                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4893                                + " from background process " + proc);
4894                        return;
4895                    }
4896                }
4897                closeSystemDialogsLocked(reason);
4898            }
4899        } finally {
4900            Binder.restoreCallingIdentity(origId);
4901        }
4902    }
4903
4904    void closeSystemDialogsLocked(String reason) {
4905        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4906        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4907                | Intent.FLAG_RECEIVER_FOREGROUND);
4908        if (reason != null) {
4909            intent.putExtra("reason", reason);
4910        }
4911        mWindowManager.closeSystemDialogs(reason);
4912
4913        mStackSupervisor.closeSystemDialogsLocked();
4914
4915        broadcastIntentLocked(null, null, intent, null,
4916                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4917                Process.SYSTEM_UID, UserHandle.USER_ALL);
4918    }
4919
4920    @Override
4921    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4922        enforceNotIsolatedCaller("getProcessMemoryInfo");
4923        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4924        for (int i=pids.length-1; i>=0; i--) {
4925            ProcessRecord proc;
4926            int oomAdj;
4927            synchronized (this) {
4928                synchronized (mPidsSelfLocked) {
4929                    proc = mPidsSelfLocked.get(pids[i]);
4930                    oomAdj = proc != null ? proc.setAdj : 0;
4931                }
4932            }
4933            infos[i] = new Debug.MemoryInfo();
4934            Debug.getMemoryInfo(pids[i], infos[i]);
4935            if (proc != null) {
4936                synchronized (this) {
4937                    if (proc.thread != null && proc.setAdj == oomAdj) {
4938                        // Record this for posterity if the process has been stable.
4939                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4940                                infos[i].getTotalUss(), false, proc.pkgList);
4941                    }
4942                }
4943            }
4944        }
4945        return infos;
4946    }
4947
4948    @Override
4949    public long[] getProcessPss(int[] pids) {
4950        enforceNotIsolatedCaller("getProcessPss");
4951        long[] pss = new long[pids.length];
4952        for (int i=pids.length-1; i>=0; i--) {
4953            ProcessRecord proc;
4954            int oomAdj;
4955            synchronized (this) {
4956                synchronized (mPidsSelfLocked) {
4957                    proc = mPidsSelfLocked.get(pids[i]);
4958                    oomAdj = proc != null ? proc.setAdj : 0;
4959                }
4960            }
4961            long[] tmpUss = new long[1];
4962            pss[i] = Debug.getPss(pids[i], tmpUss);
4963            if (proc != null) {
4964                synchronized (this) {
4965                    if (proc.thread != null && proc.setAdj == oomAdj) {
4966                        // Record this for posterity if the process has been stable.
4967                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4968                    }
4969                }
4970            }
4971        }
4972        return pss;
4973    }
4974
4975    @Override
4976    public void killApplicationProcess(String processName, int uid) {
4977        if (processName == null) {
4978            return;
4979        }
4980
4981        int callerUid = Binder.getCallingUid();
4982        // Only the system server can kill an application
4983        if (callerUid == Process.SYSTEM_UID) {
4984            synchronized (this) {
4985                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4986                if (app != null && app.thread != null) {
4987                    try {
4988                        app.thread.scheduleSuicide();
4989                    } catch (RemoteException e) {
4990                        // If the other end already died, then our work here is done.
4991                    }
4992                } else {
4993                    Slog.w(TAG, "Process/uid not found attempting kill of "
4994                            + processName + " / " + uid);
4995                }
4996            }
4997        } else {
4998            throw new SecurityException(callerUid + " cannot kill app process: " +
4999                    processName);
5000        }
5001    }
5002
5003    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5004        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5005                false, true, false, false, UserHandle.getUserId(uid), reason);
5006        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5007                Uri.fromParts("package", packageName, null));
5008        if (!mProcessesReady) {
5009            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5010                    | Intent.FLAG_RECEIVER_FOREGROUND);
5011        }
5012        intent.putExtra(Intent.EXTRA_UID, uid);
5013        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5014        broadcastIntentLocked(null, null, intent,
5015                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5016                false, false,
5017                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5018    }
5019
5020    private void forceStopUserLocked(int userId, String reason) {
5021        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5022        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5023        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5024                | Intent.FLAG_RECEIVER_FOREGROUND);
5025        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5026        broadcastIntentLocked(null, null, intent,
5027                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5028                false, false,
5029                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5030    }
5031
5032    private final boolean killPackageProcessesLocked(String packageName, int appId,
5033            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5034            boolean doit, boolean evenPersistent, String reason) {
5035        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5036
5037        // Remove all processes this package may have touched: all with the
5038        // same UID (except for the system or root user), and all whose name
5039        // matches the package name.
5040        final int NP = mProcessNames.getMap().size();
5041        for (int ip=0; ip<NP; ip++) {
5042            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5043            final int NA = apps.size();
5044            for (int ia=0; ia<NA; ia++) {
5045                ProcessRecord app = apps.valueAt(ia);
5046                if (app.persistent && !evenPersistent) {
5047                    // we don't kill persistent processes
5048                    continue;
5049                }
5050                if (app.removed) {
5051                    if (doit) {
5052                        procs.add(app);
5053                    }
5054                    continue;
5055                }
5056
5057                // Skip process if it doesn't meet our oom adj requirement.
5058                if (app.setAdj < minOomAdj) {
5059                    continue;
5060                }
5061
5062                // If no package is specified, we call all processes under the
5063                // give user id.
5064                if (packageName == null) {
5065                    if (app.userId != userId) {
5066                        continue;
5067                    }
5068                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5069                        continue;
5070                    }
5071                // Package has been specified, we want to hit all processes
5072                // that match it.  We need to qualify this by the processes
5073                // that are running under the specified app and user ID.
5074                } else {
5075                    final boolean isDep = app.pkgDeps != null
5076                            && app.pkgDeps.contains(packageName);
5077                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5078                        continue;
5079                    }
5080                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5081                        continue;
5082                    }
5083                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5084                        continue;
5085                    }
5086                }
5087
5088                // Process has passed all conditions, kill it!
5089                if (!doit) {
5090                    return true;
5091                }
5092                app.removed = true;
5093                procs.add(app);
5094            }
5095        }
5096
5097        int N = procs.size();
5098        for (int i=0; i<N; i++) {
5099            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5100        }
5101        updateOomAdjLocked();
5102        return N > 0;
5103    }
5104
5105    private final boolean forceStopPackageLocked(String name, int appId,
5106            boolean callerWillRestart, boolean purgeCache, boolean doit,
5107            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5108        int i;
5109        int N;
5110
5111        if (userId == UserHandle.USER_ALL && name == null) {
5112            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5113        }
5114
5115        if (appId < 0 && name != null) {
5116            try {
5117                appId = UserHandle.getAppId(
5118                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5119            } catch (RemoteException e) {
5120            }
5121        }
5122
5123        if (doit) {
5124            if (name != null) {
5125                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5126                        + " user=" + userId + ": " + reason);
5127            } else {
5128                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5129            }
5130
5131            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5132            for (int ip=pmap.size()-1; ip>=0; ip--) {
5133                SparseArray<Long> ba = pmap.valueAt(ip);
5134                for (i=ba.size()-1; i>=0; i--) {
5135                    boolean remove = false;
5136                    final int entUid = ba.keyAt(i);
5137                    if (name != null) {
5138                        if (userId == UserHandle.USER_ALL) {
5139                            if (UserHandle.getAppId(entUid) == appId) {
5140                                remove = true;
5141                            }
5142                        } else {
5143                            if (entUid == UserHandle.getUid(userId, appId)) {
5144                                remove = true;
5145                            }
5146                        }
5147                    } else if (UserHandle.getUserId(entUid) == userId) {
5148                        remove = true;
5149                    }
5150                    if (remove) {
5151                        ba.removeAt(i);
5152                    }
5153                }
5154                if (ba.size() == 0) {
5155                    pmap.removeAt(ip);
5156                }
5157            }
5158        }
5159
5160        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5161                -100, callerWillRestart, true, doit, evenPersistent,
5162                name == null ? ("stop user " + userId) : ("stop " + name));
5163
5164        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5165            if (!doit) {
5166                return true;
5167            }
5168            didSomething = true;
5169        }
5170
5171        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5172            if (!doit) {
5173                return true;
5174            }
5175            didSomething = true;
5176        }
5177
5178        if (name == null) {
5179            // Remove all sticky broadcasts from this user.
5180            mStickyBroadcasts.remove(userId);
5181        }
5182
5183        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5184        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5185                userId, providers)) {
5186            if (!doit) {
5187                return true;
5188            }
5189            didSomething = true;
5190        }
5191        N = providers.size();
5192        for (i=0; i<N; i++) {
5193            removeDyingProviderLocked(null, providers.get(i), true);
5194        }
5195
5196        // Remove transient permissions granted from/to this package/user
5197        removeUriPermissionsForPackageLocked(name, userId, false);
5198
5199        if (name == null || uninstalling) {
5200            // Remove pending intents.  For now we only do this when force
5201            // stopping users, because we have some problems when doing this
5202            // for packages -- app widgets are not currently cleaned up for
5203            // such packages, so they can be left with bad pending intents.
5204            if (mIntentSenderRecords.size() > 0) {
5205                Iterator<WeakReference<PendingIntentRecord>> it
5206                        = mIntentSenderRecords.values().iterator();
5207                while (it.hasNext()) {
5208                    WeakReference<PendingIntentRecord> wpir = it.next();
5209                    if (wpir == null) {
5210                        it.remove();
5211                        continue;
5212                    }
5213                    PendingIntentRecord pir = wpir.get();
5214                    if (pir == null) {
5215                        it.remove();
5216                        continue;
5217                    }
5218                    if (name == null) {
5219                        // Stopping user, remove all objects for the user.
5220                        if (pir.key.userId != userId) {
5221                            // Not the same user, skip it.
5222                            continue;
5223                        }
5224                    } else {
5225                        if (UserHandle.getAppId(pir.uid) != appId) {
5226                            // Different app id, skip it.
5227                            continue;
5228                        }
5229                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5230                            // Different user, skip it.
5231                            continue;
5232                        }
5233                        if (!pir.key.packageName.equals(name)) {
5234                            // Different package, skip it.
5235                            continue;
5236                        }
5237                    }
5238                    if (!doit) {
5239                        return true;
5240                    }
5241                    didSomething = true;
5242                    it.remove();
5243                    pir.canceled = true;
5244                    if (pir.key.activity != null) {
5245                        pir.key.activity.pendingResults.remove(pir.ref);
5246                    }
5247                }
5248            }
5249        }
5250
5251        if (doit) {
5252            if (purgeCache && name != null) {
5253                AttributeCache ac = AttributeCache.instance();
5254                if (ac != null) {
5255                    ac.removePackage(name);
5256                }
5257            }
5258            if (mBooted) {
5259                mStackSupervisor.resumeTopActivitiesLocked();
5260                mStackSupervisor.scheduleIdleLocked();
5261            }
5262        }
5263
5264        return didSomething;
5265    }
5266
5267    private final boolean removeProcessLocked(ProcessRecord app,
5268            boolean callerWillRestart, boolean allowRestart, String reason) {
5269        final String name = app.processName;
5270        final int uid = app.uid;
5271        if (DEBUG_PROCESSES) Slog.d(
5272            TAG, "Force removing proc " + app.toShortString() + " (" + name
5273            + "/" + uid + ")");
5274
5275        mProcessNames.remove(name, uid);
5276        mIsolatedProcesses.remove(app.uid);
5277        if (mHeavyWeightProcess == app) {
5278            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5279                    mHeavyWeightProcess.userId, 0));
5280            mHeavyWeightProcess = null;
5281        }
5282        boolean needRestart = false;
5283        if (app.pid > 0 && app.pid != MY_PID) {
5284            int pid = app.pid;
5285            synchronized (mPidsSelfLocked) {
5286                mPidsSelfLocked.remove(pid);
5287                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5288            }
5289            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5290            if (app.isolated) {
5291                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5292            }
5293            killUnneededProcessLocked(app, reason);
5294            Process.killProcessGroup(app.info.uid, app.pid);
5295            handleAppDiedLocked(app, true, allowRestart);
5296            removeLruProcessLocked(app);
5297
5298            if (app.persistent && !app.isolated) {
5299                if (!callerWillRestart) {
5300                    addAppLocked(app.info, false, null /* ABI override */);
5301                } else {
5302                    needRestart = true;
5303                }
5304            }
5305        } else {
5306            mRemovedProcesses.add(app);
5307        }
5308
5309        return needRestart;
5310    }
5311
5312    private final void processStartTimedOutLocked(ProcessRecord app) {
5313        final int pid = app.pid;
5314        boolean gone = false;
5315        synchronized (mPidsSelfLocked) {
5316            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5317            if (knownApp != null && knownApp.thread == null) {
5318                mPidsSelfLocked.remove(pid);
5319                gone = true;
5320            }
5321        }
5322
5323        if (gone) {
5324            Slog.w(TAG, "Process " + app + " failed to attach");
5325            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5326                    pid, app.uid, app.processName);
5327            mProcessNames.remove(app.processName, app.uid);
5328            mIsolatedProcesses.remove(app.uid);
5329            if (mHeavyWeightProcess == app) {
5330                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5331                        mHeavyWeightProcess.userId, 0));
5332                mHeavyWeightProcess = null;
5333            }
5334            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5335            if (app.isolated) {
5336                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5337            }
5338            // Take care of any launching providers waiting for this process.
5339            checkAppInLaunchingProvidersLocked(app, true);
5340            // Take care of any services that are waiting for the process.
5341            mServices.processStartTimedOutLocked(app);
5342            killUnneededProcessLocked(app, "start timeout");
5343            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5344                Slog.w(TAG, "Unattached app died before backup, skipping");
5345                try {
5346                    IBackupManager bm = IBackupManager.Stub.asInterface(
5347                            ServiceManager.getService(Context.BACKUP_SERVICE));
5348                    bm.agentDisconnected(app.info.packageName);
5349                } catch (RemoteException e) {
5350                    // Can't happen; the backup manager is local
5351                }
5352            }
5353            if (isPendingBroadcastProcessLocked(pid)) {
5354                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5355                skipPendingBroadcastLocked(pid);
5356            }
5357        } else {
5358            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5359        }
5360    }
5361
5362    private final boolean attachApplicationLocked(IApplicationThread thread,
5363            int pid) {
5364
5365        // Find the application record that is being attached...  either via
5366        // the pid if we are running in multiple processes, or just pull the
5367        // next app record if we are emulating process with anonymous threads.
5368        ProcessRecord app;
5369        if (pid != MY_PID && pid >= 0) {
5370            synchronized (mPidsSelfLocked) {
5371                app = mPidsSelfLocked.get(pid);
5372            }
5373        } else {
5374            app = null;
5375        }
5376
5377        if (app == null) {
5378            Slog.w(TAG, "No pending application record for pid " + pid
5379                    + " (IApplicationThread " + thread + "); dropping process");
5380            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5381            if (pid > 0 && pid != MY_PID) {
5382                Process.killProcessQuiet(pid);
5383                //TODO: Process.killProcessGroup(app.info.uid, pid);
5384            } else {
5385                try {
5386                    thread.scheduleExit();
5387                } catch (Exception e) {
5388                    // Ignore exceptions.
5389                }
5390            }
5391            return false;
5392        }
5393
5394        // If this application record is still attached to a previous
5395        // process, clean it up now.
5396        if (app.thread != null) {
5397            handleAppDiedLocked(app, true, true);
5398        }
5399
5400        // Tell the process all about itself.
5401
5402        if (localLOGV) Slog.v(
5403                TAG, "Binding process pid " + pid + " to record " + app);
5404
5405        final String processName = app.processName;
5406        try {
5407            AppDeathRecipient adr = new AppDeathRecipient(
5408                    app, pid, thread);
5409            thread.asBinder().linkToDeath(adr, 0);
5410            app.deathRecipient = adr;
5411        } catch (RemoteException e) {
5412            app.resetPackageList(mProcessStats);
5413            startProcessLocked(app, "link fail", processName);
5414            return false;
5415        }
5416
5417        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5418
5419        app.makeActive(thread, mProcessStats);
5420        app.curAdj = app.setAdj = -100;
5421        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5422        app.forcingToForeground = null;
5423        updateProcessForegroundLocked(app, false, false);
5424        app.hasShownUi = false;
5425        app.debugging = false;
5426        app.cached = false;
5427
5428        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5429
5430        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5431        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5432
5433        if (!normalMode) {
5434            Slog.i(TAG, "Launching preboot mode app: " + app);
5435        }
5436
5437        if (localLOGV) Slog.v(
5438            TAG, "New app record " + app
5439            + " thread=" + thread.asBinder() + " pid=" + pid);
5440        try {
5441            int testMode = IApplicationThread.DEBUG_OFF;
5442            if (mDebugApp != null && mDebugApp.equals(processName)) {
5443                testMode = mWaitForDebugger
5444                    ? IApplicationThread.DEBUG_WAIT
5445                    : IApplicationThread.DEBUG_ON;
5446                app.debugging = true;
5447                if (mDebugTransient) {
5448                    mDebugApp = mOrigDebugApp;
5449                    mWaitForDebugger = mOrigWaitForDebugger;
5450                }
5451            }
5452            String profileFile = app.instrumentationProfileFile;
5453            ParcelFileDescriptor profileFd = null;
5454            boolean profileAutoStop = false;
5455            if (mProfileApp != null && mProfileApp.equals(processName)) {
5456                mProfileProc = app;
5457                profileFile = mProfileFile;
5458                profileFd = mProfileFd;
5459                profileAutoStop = mAutoStopProfiler;
5460            }
5461            boolean enableOpenGlTrace = false;
5462            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5463                enableOpenGlTrace = true;
5464                mOpenGlTraceApp = null;
5465            }
5466
5467            // If the app is being launched for restore or full backup, set it up specially
5468            boolean isRestrictedBackupMode = false;
5469            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5470                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5471                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5472                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5473            }
5474
5475            ensurePackageDexOpt(app.instrumentationInfo != null
5476                    ? app.instrumentationInfo.packageName
5477                    : app.info.packageName);
5478            if (app.instrumentationClass != null) {
5479                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5480            }
5481            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5482                    + processName + " with config " + mConfiguration);
5483            ApplicationInfo appInfo = app.instrumentationInfo != null
5484                    ? app.instrumentationInfo : app.info;
5485            app.compat = compatibilityInfoForPackageLocked(appInfo);
5486            if (profileFd != null) {
5487                profileFd = profileFd.dup();
5488            }
5489            thread.bindApplication(processName, appInfo, providers,
5490                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5491                    app.instrumentationArguments, app.instrumentationWatcher,
5492                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5493                    isRestrictedBackupMode || !normalMode, app.persistent,
5494                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5495                    mCoreSettingsObserver.getCoreSettingsLocked());
5496            updateLruProcessLocked(app, false, null);
5497            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5498        } catch (Exception e) {
5499            // todo: Yikes!  What should we do?  For now we will try to
5500            // start another process, but that could easily get us in
5501            // an infinite loop of restarting processes...
5502            Slog.w(TAG, "Exception thrown during bind!", e);
5503
5504            app.resetPackageList(mProcessStats);
5505            app.unlinkDeathRecipient();
5506            startProcessLocked(app, "bind fail", processName);
5507            return false;
5508        }
5509
5510        // Remove this record from the list of starting applications.
5511        mPersistentStartingProcesses.remove(app);
5512        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5513                "Attach application locked removing on hold: " + app);
5514        mProcessesOnHold.remove(app);
5515
5516        boolean badApp = false;
5517        boolean didSomething = false;
5518
5519        // See if the top visible activity is waiting to run in this process...
5520        if (normalMode) {
5521            try {
5522                if (mStackSupervisor.attachApplicationLocked(app)) {
5523                    didSomething = true;
5524                }
5525            } catch (Exception e) {
5526                badApp = true;
5527            }
5528        }
5529
5530        // Find any services that should be running in this process...
5531        if (!badApp) {
5532            try {
5533                didSomething |= mServices.attachApplicationLocked(app, processName);
5534            } catch (Exception e) {
5535                badApp = true;
5536            }
5537        }
5538
5539        // Check if a next-broadcast receiver is in this process...
5540        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5541            try {
5542                didSomething |= sendPendingBroadcastsLocked(app);
5543            } catch (Exception e) {
5544                // If the app died trying to launch the receiver we declare it 'bad'
5545                badApp = true;
5546            }
5547        }
5548
5549        // Check whether the next backup agent is in this process...
5550        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5551            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5552            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5553            try {
5554                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5555                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5556                        mBackupTarget.backupMode);
5557            } catch (Exception e) {
5558                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5559                e.printStackTrace();
5560            }
5561        }
5562
5563        if (badApp) {
5564            // todo: Also need to kill application to deal with all
5565            // kinds of exceptions.
5566            handleAppDiedLocked(app, false, true);
5567            return false;
5568        }
5569
5570        if (!didSomething) {
5571            updateOomAdjLocked();
5572        }
5573
5574        return true;
5575    }
5576
5577    @Override
5578    public final void attachApplication(IApplicationThread thread) {
5579        synchronized (this) {
5580            int callingPid = Binder.getCallingPid();
5581            final long origId = Binder.clearCallingIdentity();
5582            attachApplicationLocked(thread, callingPid);
5583            Binder.restoreCallingIdentity(origId);
5584        }
5585    }
5586
5587    @Override
5588    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5589        final long origId = Binder.clearCallingIdentity();
5590        synchronized (this) {
5591            ActivityStack stack = ActivityRecord.getStackLocked(token);
5592            if (stack != null) {
5593                ActivityRecord r =
5594                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5595                if (stopProfiling) {
5596                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5597                        try {
5598                            mProfileFd.close();
5599                        } catch (IOException e) {
5600                        }
5601                        clearProfilerLocked();
5602                    }
5603                }
5604            }
5605        }
5606        Binder.restoreCallingIdentity(origId);
5607    }
5608
5609    void postEnableScreenAfterBootLocked() {
5610        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5611    }
5612
5613    void enableScreenAfterBoot() {
5614        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5615                SystemClock.uptimeMillis());
5616        mWindowManager.enableScreenAfterBoot();
5617
5618        synchronized (this) {
5619            updateEventDispatchingLocked();
5620        }
5621    }
5622
5623    @Override
5624    public void showBootMessage(final CharSequence msg, final boolean always) {
5625        enforceNotIsolatedCaller("showBootMessage");
5626        mWindowManager.showBootMessage(msg, always);
5627    }
5628
5629    @Override
5630    public void dismissKeyguardOnNextActivity() {
5631        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5632        final long token = Binder.clearCallingIdentity();
5633        try {
5634            synchronized (this) {
5635                if (DEBUG_LOCKSCREEN) logLockScreen("");
5636                if (mLockScreenShown) {
5637                    mLockScreenShown = false;
5638                    comeOutOfSleepIfNeededLocked();
5639                }
5640                mStackSupervisor.setDismissKeyguard(true);
5641            }
5642        } finally {
5643            Binder.restoreCallingIdentity(token);
5644        }
5645    }
5646
5647    final void finishBooting() {
5648        // Register receivers to handle package update events
5649        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5650
5651        // Let system services know.
5652        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
5653
5654        synchronized (this) {
5655            // Ensure that any processes we had put on hold are now started
5656            // up.
5657            final int NP = mProcessesOnHold.size();
5658            if (NP > 0) {
5659                ArrayList<ProcessRecord> procs =
5660                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5661                for (int ip=0; ip<NP; ip++) {
5662                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5663                            + procs.get(ip));
5664                    startProcessLocked(procs.get(ip), "on-hold", null);
5665                }
5666            }
5667
5668            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5669                // Start looking for apps that are abusing wake locks.
5670                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5671                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5672                // Tell anyone interested that we are done booting!
5673                SystemProperties.set("sys.boot_completed", "1");
5674                SystemProperties.set("dev.bootcomplete", "1");
5675                for (int i=0; i<mStartedUsers.size(); i++) {
5676                    UserStartedState uss = mStartedUsers.valueAt(i);
5677                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5678                        uss.mState = UserStartedState.STATE_RUNNING;
5679                        final int userId = mStartedUsers.keyAt(i);
5680                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5681                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5682                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5683                        broadcastIntentLocked(null, null, intent, null,
5684                                new IIntentReceiver.Stub() {
5685                                    @Override
5686                                    public void performReceive(Intent intent, int resultCode,
5687                                            String data, Bundle extras, boolean ordered,
5688                                            boolean sticky, int sendingUser) {
5689                                        synchronized (ActivityManagerService.this) {
5690                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5691                                                    true, false);
5692                                        }
5693                                    }
5694                                },
5695                                0, null, null,
5696                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5697                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5698                                userId);
5699                    }
5700                }
5701                scheduleStartProfilesLocked();
5702            }
5703        }
5704    }
5705
5706    final void ensureBootCompleted() {
5707        boolean booting;
5708        boolean enableScreen;
5709        synchronized (this) {
5710            booting = mBooting;
5711            mBooting = false;
5712            enableScreen = !mBooted;
5713            mBooted = true;
5714        }
5715
5716        if (booting) {
5717            finishBooting();
5718        }
5719
5720        if (enableScreen) {
5721            enableScreenAfterBoot();
5722        }
5723    }
5724
5725    @Override
5726    public final void activityResumed(IBinder token) {
5727        final long origId = Binder.clearCallingIdentity();
5728        synchronized(this) {
5729            ActivityStack stack = ActivityRecord.getStackLocked(token);
5730            if (stack != null) {
5731                ActivityRecord.activityResumedLocked(token);
5732            }
5733        }
5734        Binder.restoreCallingIdentity(origId);
5735    }
5736
5737    @Override
5738    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5739        final long origId = Binder.clearCallingIdentity();
5740        synchronized(this) {
5741            ActivityStack stack = ActivityRecord.getStackLocked(token);
5742            if (stack != null) {
5743                stack.activityPausedLocked(token, false, persistentState);
5744            }
5745        }
5746        Binder.restoreCallingIdentity(origId);
5747    }
5748
5749    @Override
5750    public final void activityStopped(IBinder token, Bundle icicle,
5751            PersistableBundle persistentState, CharSequence description) {
5752        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5753
5754        // Refuse possible leaked file descriptors
5755        if (icicle != null && icicle.hasFileDescriptors()) {
5756            throw new IllegalArgumentException("File descriptors passed in Bundle");
5757        }
5758
5759        final long origId = Binder.clearCallingIdentity();
5760
5761        synchronized (this) {
5762            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5763            if (r != null) {
5764                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5765            }
5766        }
5767
5768        trimApplications();
5769
5770        Binder.restoreCallingIdentity(origId);
5771    }
5772
5773    @Override
5774    public final void activityDestroyed(IBinder token) {
5775        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5776        synchronized (this) {
5777            ActivityStack stack = ActivityRecord.getStackLocked(token);
5778            if (stack != null) {
5779                stack.activityDestroyedLocked(token);
5780            }
5781        }
5782    }
5783
5784    @Override
5785    public final void mediaResourcesReleased(IBinder token) {
5786        final long origId = Binder.clearCallingIdentity();
5787        try {
5788            synchronized (this) {
5789                ActivityStack stack = ActivityRecord.getStackLocked(token);
5790                if (stack != null) {
5791                    stack.mediaResourcesReleased(token);
5792                }
5793            }
5794        } finally {
5795            Binder.restoreCallingIdentity(origId);
5796        }
5797    }
5798
5799    @Override
5800    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5801        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5802    }
5803
5804    @Override
5805    public final void notifyEnterAnimationComplete(IBinder token) {
5806        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5807    }
5808
5809    @Override
5810    public String getCallingPackage(IBinder token) {
5811        synchronized (this) {
5812            ActivityRecord r = getCallingRecordLocked(token);
5813            return r != null ? r.info.packageName : null;
5814        }
5815    }
5816
5817    @Override
5818    public ComponentName getCallingActivity(IBinder token) {
5819        synchronized (this) {
5820            ActivityRecord r = getCallingRecordLocked(token);
5821            return r != null ? r.intent.getComponent() : null;
5822        }
5823    }
5824
5825    private ActivityRecord getCallingRecordLocked(IBinder token) {
5826        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5827        if (r == null) {
5828            return null;
5829        }
5830        return r.resultTo;
5831    }
5832
5833    @Override
5834    public ComponentName getActivityClassForToken(IBinder token) {
5835        synchronized(this) {
5836            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5837            if (r == null) {
5838                return null;
5839            }
5840            return r.intent.getComponent();
5841        }
5842    }
5843
5844    @Override
5845    public String getPackageForToken(IBinder token) {
5846        synchronized(this) {
5847            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5848            if (r == null) {
5849                return null;
5850            }
5851            return r.packageName;
5852        }
5853    }
5854
5855    @Override
5856    public IIntentSender getIntentSender(int type,
5857            String packageName, IBinder token, String resultWho,
5858            int requestCode, Intent[] intents, String[] resolvedTypes,
5859            int flags, Bundle options, int userId) {
5860        enforceNotIsolatedCaller("getIntentSender");
5861        // Refuse possible leaked file descriptors
5862        if (intents != null) {
5863            if (intents.length < 1) {
5864                throw new IllegalArgumentException("Intents array length must be >= 1");
5865            }
5866            for (int i=0; i<intents.length; i++) {
5867                Intent intent = intents[i];
5868                if (intent != null) {
5869                    if (intent.hasFileDescriptors()) {
5870                        throw new IllegalArgumentException("File descriptors passed in Intent");
5871                    }
5872                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5873                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5874                        throw new IllegalArgumentException(
5875                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5876                    }
5877                    intents[i] = new Intent(intent);
5878                }
5879            }
5880            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5881                throw new IllegalArgumentException(
5882                        "Intent array length does not match resolvedTypes length");
5883            }
5884        }
5885        if (options != null) {
5886            if (options.hasFileDescriptors()) {
5887                throw new IllegalArgumentException("File descriptors passed in options");
5888            }
5889        }
5890
5891        synchronized(this) {
5892            int callingUid = Binder.getCallingUid();
5893            int origUserId = userId;
5894            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5895                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5896                    ALLOW_NON_FULL, "getIntentSender", null);
5897            if (origUserId == UserHandle.USER_CURRENT) {
5898                // We don't want to evaluate this until the pending intent is
5899                // actually executed.  However, we do want to always do the
5900                // security checking for it above.
5901                userId = UserHandle.USER_CURRENT;
5902            }
5903            try {
5904                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5905                    int uid = AppGlobals.getPackageManager()
5906                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5907                    if (!UserHandle.isSameApp(callingUid, uid)) {
5908                        String msg = "Permission Denial: getIntentSender() from pid="
5909                            + Binder.getCallingPid()
5910                            + ", uid=" + Binder.getCallingUid()
5911                            + ", (need uid=" + uid + ")"
5912                            + " is not allowed to send as package " + packageName;
5913                        Slog.w(TAG, msg);
5914                        throw new SecurityException(msg);
5915                    }
5916                }
5917
5918                return getIntentSenderLocked(type, packageName, callingUid, userId,
5919                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5920
5921            } catch (RemoteException e) {
5922                throw new SecurityException(e);
5923            }
5924        }
5925    }
5926
5927    IIntentSender getIntentSenderLocked(int type, String packageName,
5928            int callingUid, int userId, IBinder token, String resultWho,
5929            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5930            Bundle options) {
5931        if (DEBUG_MU)
5932            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5933        ActivityRecord activity = null;
5934        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5935            activity = ActivityRecord.isInStackLocked(token);
5936            if (activity == null) {
5937                return null;
5938            }
5939            if (activity.finishing) {
5940                return null;
5941            }
5942        }
5943
5944        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5945        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5946        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5947        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5948                |PendingIntent.FLAG_UPDATE_CURRENT);
5949
5950        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5951                type, packageName, activity, resultWho,
5952                requestCode, intents, resolvedTypes, flags, options, userId);
5953        WeakReference<PendingIntentRecord> ref;
5954        ref = mIntentSenderRecords.get(key);
5955        PendingIntentRecord rec = ref != null ? ref.get() : null;
5956        if (rec != null) {
5957            if (!cancelCurrent) {
5958                if (updateCurrent) {
5959                    if (rec.key.requestIntent != null) {
5960                        rec.key.requestIntent.replaceExtras(intents != null ?
5961                                intents[intents.length - 1] : null);
5962                    }
5963                    if (intents != null) {
5964                        intents[intents.length-1] = rec.key.requestIntent;
5965                        rec.key.allIntents = intents;
5966                        rec.key.allResolvedTypes = resolvedTypes;
5967                    } else {
5968                        rec.key.allIntents = null;
5969                        rec.key.allResolvedTypes = null;
5970                    }
5971                }
5972                return rec;
5973            }
5974            rec.canceled = true;
5975            mIntentSenderRecords.remove(key);
5976        }
5977        if (noCreate) {
5978            return rec;
5979        }
5980        rec = new PendingIntentRecord(this, key, callingUid);
5981        mIntentSenderRecords.put(key, rec.ref);
5982        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5983            if (activity.pendingResults == null) {
5984                activity.pendingResults
5985                        = new HashSet<WeakReference<PendingIntentRecord>>();
5986            }
5987            activity.pendingResults.add(rec.ref);
5988        }
5989        return rec;
5990    }
5991
5992    @Override
5993    public void cancelIntentSender(IIntentSender sender) {
5994        if (!(sender instanceof PendingIntentRecord)) {
5995            return;
5996        }
5997        synchronized(this) {
5998            PendingIntentRecord rec = (PendingIntentRecord)sender;
5999            try {
6000                int uid = AppGlobals.getPackageManager()
6001                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6002                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6003                    String msg = "Permission Denial: cancelIntentSender() from pid="
6004                        + Binder.getCallingPid()
6005                        + ", uid=" + Binder.getCallingUid()
6006                        + " is not allowed to cancel packges "
6007                        + rec.key.packageName;
6008                    Slog.w(TAG, msg);
6009                    throw new SecurityException(msg);
6010                }
6011            } catch (RemoteException e) {
6012                throw new SecurityException(e);
6013            }
6014            cancelIntentSenderLocked(rec, true);
6015        }
6016    }
6017
6018    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6019        rec.canceled = true;
6020        mIntentSenderRecords.remove(rec.key);
6021        if (cleanActivity && rec.key.activity != null) {
6022            rec.key.activity.pendingResults.remove(rec.ref);
6023        }
6024    }
6025
6026    @Override
6027    public String getPackageForIntentSender(IIntentSender pendingResult) {
6028        if (!(pendingResult instanceof PendingIntentRecord)) {
6029            return null;
6030        }
6031        try {
6032            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6033            return res.key.packageName;
6034        } catch (ClassCastException e) {
6035        }
6036        return null;
6037    }
6038
6039    @Override
6040    public int getUidForIntentSender(IIntentSender sender) {
6041        if (sender instanceof PendingIntentRecord) {
6042            try {
6043                PendingIntentRecord res = (PendingIntentRecord)sender;
6044                return res.uid;
6045            } catch (ClassCastException e) {
6046            }
6047        }
6048        return -1;
6049    }
6050
6051    @Override
6052    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6053        if (!(pendingResult instanceof PendingIntentRecord)) {
6054            return false;
6055        }
6056        try {
6057            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6058            if (res.key.allIntents == null) {
6059                return false;
6060            }
6061            for (int i=0; i<res.key.allIntents.length; i++) {
6062                Intent intent = res.key.allIntents[i];
6063                if (intent.getPackage() != null && intent.getComponent() != null) {
6064                    return false;
6065                }
6066            }
6067            return true;
6068        } catch (ClassCastException e) {
6069        }
6070        return false;
6071    }
6072
6073    @Override
6074    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6075        if (!(pendingResult instanceof PendingIntentRecord)) {
6076            return false;
6077        }
6078        try {
6079            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6080            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6081                return true;
6082            }
6083            return false;
6084        } catch (ClassCastException e) {
6085        }
6086        return false;
6087    }
6088
6089    @Override
6090    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6091        if (!(pendingResult instanceof PendingIntentRecord)) {
6092            return null;
6093        }
6094        try {
6095            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6096            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6097        } catch (ClassCastException e) {
6098        }
6099        return null;
6100    }
6101
6102    @Override
6103    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6104        if (!(pendingResult instanceof PendingIntentRecord)) {
6105            return null;
6106        }
6107        try {
6108            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6109            Intent intent = res.key.requestIntent;
6110            if (intent != null) {
6111                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6112                        || res.lastTagPrefix.equals(prefix))) {
6113                    return res.lastTag;
6114                }
6115                res.lastTagPrefix = prefix;
6116                StringBuilder sb = new StringBuilder(128);
6117                if (prefix != null) {
6118                    sb.append(prefix);
6119                }
6120                if (intent.getAction() != null) {
6121                    sb.append(intent.getAction());
6122                } else if (intent.getComponent() != null) {
6123                    intent.getComponent().appendShortString(sb);
6124                } else {
6125                    sb.append("?");
6126                }
6127                return res.lastTag = sb.toString();
6128            }
6129        } catch (ClassCastException e) {
6130        }
6131        return null;
6132    }
6133
6134    @Override
6135    public void setProcessLimit(int max) {
6136        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6137                "setProcessLimit()");
6138        synchronized (this) {
6139            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6140            mProcessLimitOverride = max;
6141        }
6142        trimApplications();
6143    }
6144
6145    @Override
6146    public int getProcessLimit() {
6147        synchronized (this) {
6148            return mProcessLimitOverride;
6149        }
6150    }
6151
6152    void foregroundTokenDied(ForegroundToken token) {
6153        synchronized (ActivityManagerService.this) {
6154            synchronized (mPidsSelfLocked) {
6155                ForegroundToken cur
6156                    = mForegroundProcesses.get(token.pid);
6157                if (cur != token) {
6158                    return;
6159                }
6160                mForegroundProcesses.remove(token.pid);
6161                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6162                if (pr == null) {
6163                    return;
6164                }
6165                pr.forcingToForeground = null;
6166                updateProcessForegroundLocked(pr, false, false);
6167            }
6168            updateOomAdjLocked();
6169        }
6170    }
6171
6172    @Override
6173    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6174        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6175                "setProcessForeground()");
6176        synchronized(this) {
6177            boolean changed = false;
6178
6179            synchronized (mPidsSelfLocked) {
6180                ProcessRecord pr = mPidsSelfLocked.get(pid);
6181                if (pr == null && isForeground) {
6182                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6183                    return;
6184                }
6185                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6186                if (oldToken != null) {
6187                    oldToken.token.unlinkToDeath(oldToken, 0);
6188                    mForegroundProcesses.remove(pid);
6189                    if (pr != null) {
6190                        pr.forcingToForeground = null;
6191                    }
6192                    changed = true;
6193                }
6194                if (isForeground && token != null) {
6195                    ForegroundToken newToken = new ForegroundToken() {
6196                        @Override
6197                        public void binderDied() {
6198                            foregroundTokenDied(this);
6199                        }
6200                    };
6201                    newToken.pid = pid;
6202                    newToken.token = token;
6203                    try {
6204                        token.linkToDeath(newToken, 0);
6205                        mForegroundProcesses.put(pid, newToken);
6206                        pr.forcingToForeground = token;
6207                        changed = true;
6208                    } catch (RemoteException e) {
6209                        // If the process died while doing this, we will later
6210                        // do the cleanup with the process death link.
6211                    }
6212                }
6213            }
6214
6215            if (changed) {
6216                updateOomAdjLocked();
6217            }
6218        }
6219    }
6220
6221    // =========================================================
6222    // PERMISSIONS
6223    // =========================================================
6224
6225    static class PermissionController extends IPermissionController.Stub {
6226        ActivityManagerService mActivityManagerService;
6227        PermissionController(ActivityManagerService activityManagerService) {
6228            mActivityManagerService = activityManagerService;
6229        }
6230
6231        @Override
6232        public boolean checkPermission(String permission, int pid, int uid) {
6233            return mActivityManagerService.checkPermission(permission, pid,
6234                    uid) == PackageManager.PERMISSION_GRANTED;
6235        }
6236    }
6237
6238    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6239        @Override
6240        public int checkComponentPermission(String permission, int pid, int uid,
6241                int owningUid, boolean exported) {
6242            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6243                    owningUid, exported);
6244        }
6245
6246        @Override
6247        public Object getAMSLock() {
6248            return ActivityManagerService.this;
6249        }
6250    }
6251
6252    /**
6253     * This can be called with or without the global lock held.
6254     */
6255    int checkComponentPermission(String permission, int pid, int uid,
6256            int owningUid, boolean exported) {
6257        // We might be performing an operation on behalf of an indirect binder
6258        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6259        // client identity accordingly before proceeding.
6260        Identity tlsIdentity = sCallerIdentity.get();
6261        if (tlsIdentity != null) {
6262            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6263                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6264            uid = tlsIdentity.uid;
6265            pid = tlsIdentity.pid;
6266        }
6267
6268        if (pid == MY_PID) {
6269            return PackageManager.PERMISSION_GRANTED;
6270        }
6271
6272        return ActivityManager.checkComponentPermission(permission, uid,
6273                owningUid, exported);
6274    }
6275
6276    /**
6277     * As the only public entry point for permissions checking, this method
6278     * can enforce the semantic that requesting a check on a null global
6279     * permission is automatically denied.  (Internally a null permission
6280     * string is used when calling {@link #checkComponentPermission} in cases
6281     * when only uid-based security is needed.)
6282     *
6283     * This can be called with or without the global lock held.
6284     */
6285    @Override
6286    public int checkPermission(String permission, int pid, int uid) {
6287        if (permission == null) {
6288            return PackageManager.PERMISSION_DENIED;
6289        }
6290        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6291    }
6292
6293    /**
6294     * Binder IPC calls go through the public entry point.
6295     * This can be called with or without the global lock held.
6296     */
6297    int checkCallingPermission(String permission) {
6298        return checkPermission(permission,
6299                Binder.getCallingPid(),
6300                UserHandle.getAppId(Binder.getCallingUid()));
6301    }
6302
6303    /**
6304     * This can be called with or without the global lock held.
6305     */
6306    void enforceCallingPermission(String permission, String func) {
6307        if (checkCallingPermission(permission)
6308                == PackageManager.PERMISSION_GRANTED) {
6309            return;
6310        }
6311
6312        String msg = "Permission Denial: " + func + " from pid="
6313                + Binder.getCallingPid()
6314                + ", uid=" + Binder.getCallingUid()
6315                + " requires " + permission;
6316        Slog.w(TAG, msg);
6317        throw new SecurityException(msg);
6318    }
6319
6320    /**
6321     * Determine if UID is holding permissions required to access {@link Uri} in
6322     * the given {@link ProviderInfo}. Final permission checking is always done
6323     * in {@link ContentProvider}.
6324     */
6325    private final boolean checkHoldingPermissionsLocked(
6326            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6327        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6328                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6329        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6330            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6331                    != PERMISSION_GRANTED) {
6332                return false;
6333            }
6334        }
6335        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6336    }
6337
6338    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6339            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6340        if (pi.applicationInfo.uid == uid) {
6341            return true;
6342        } else if (!pi.exported) {
6343            return false;
6344        }
6345
6346        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6347        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6348        try {
6349            // check if target holds top-level <provider> permissions
6350            if (!readMet && pi.readPermission != null && considerUidPermissions
6351                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6352                readMet = true;
6353            }
6354            if (!writeMet && pi.writePermission != null && considerUidPermissions
6355                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6356                writeMet = true;
6357            }
6358
6359            // track if unprotected read/write is allowed; any denied
6360            // <path-permission> below removes this ability
6361            boolean allowDefaultRead = pi.readPermission == null;
6362            boolean allowDefaultWrite = pi.writePermission == null;
6363
6364            // check if target holds any <path-permission> that match uri
6365            final PathPermission[] pps = pi.pathPermissions;
6366            if (pps != null) {
6367                final String path = grantUri.uri.getPath();
6368                int i = pps.length;
6369                while (i > 0 && (!readMet || !writeMet)) {
6370                    i--;
6371                    PathPermission pp = pps[i];
6372                    if (pp.match(path)) {
6373                        if (!readMet) {
6374                            final String pprperm = pp.getReadPermission();
6375                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6376                                    + pprperm + " for " + pp.getPath()
6377                                    + ": match=" + pp.match(path)
6378                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6379                            if (pprperm != null) {
6380                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6381                                        == PERMISSION_GRANTED) {
6382                                    readMet = true;
6383                                } else {
6384                                    allowDefaultRead = false;
6385                                }
6386                            }
6387                        }
6388                        if (!writeMet) {
6389                            final String ppwperm = pp.getWritePermission();
6390                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6391                                    + ppwperm + " for " + pp.getPath()
6392                                    + ": match=" + pp.match(path)
6393                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6394                            if (ppwperm != null) {
6395                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6396                                        == PERMISSION_GRANTED) {
6397                                    writeMet = true;
6398                                } else {
6399                                    allowDefaultWrite = false;
6400                                }
6401                            }
6402                        }
6403                    }
6404                }
6405            }
6406
6407            // grant unprotected <provider> read/write, if not blocked by
6408            // <path-permission> above
6409            if (allowDefaultRead) readMet = true;
6410            if (allowDefaultWrite) writeMet = true;
6411
6412        } catch (RemoteException e) {
6413            return false;
6414        }
6415
6416        return readMet && writeMet;
6417    }
6418
6419    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6420        ProviderInfo pi = null;
6421        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6422        if (cpr != null) {
6423            pi = cpr.info;
6424        } else {
6425            try {
6426                pi = AppGlobals.getPackageManager().resolveContentProvider(
6427                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6428            } catch (RemoteException ex) {
6429            }
6430        }
6431        return pi;
6432    }
6433
6434    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6435        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6436        if (targetUris != null) {
6437            return targetUris.get(grantUri);
6438        }
6439        return null;
6440    }
6441
6442    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6443            String targetPkg, int targetUid, GrantUri grantUri) {
6444        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6445        if (targetUris == null) {
6446            targetUris = Maps.newArrayMap();
6447            mGrantedUriPermissions.put(targetUid, targetUris);
6448        }
6449
6450        UriPermission perm = targetUris.get(grantUri);
6451        if (perm == null) {
6452            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6453            targetUris.put(grantUri, perm);
6454        }
6455
6456        return perm;
6457    }
6458
6459    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6460            final int modeFlags) {
6461        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6462        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6463                : UriPermission.STRENGTH_OWNED;
6464
6465        // Root gets to do everything.
6466        if (uid == 0) {
6467            return true;
6468        }
6469
6470        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6471        if (perms == null) return false;
6472
6473        // First look for exact match
6474        final UriPermission exactPerm = perms.get(grantUri);
6475        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6476            return true;
6477        }
6478
6479        // No exact match, look for prefixes
6480        final int N = perms.size();
6481        for (int i = 0; i < N; i++) {
6482            final UriPermission perm = perms.valueAt(i);
6483            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6484                    && perm.getStrength(modeFlags) >= minStrength) {
6485                return true;
6486            }
6487        }
6488
6489        return false;
6490    }
6491
6492    @Override
6493    public int checkUriPermission(Uri uri, int pid, int uid,
6494            final int modeFlags, int userId) {
6495        enforceNotIsolatedCaller("checkUriPermission");
6496
6497        // Another redirected-binder-call permissions check as in
6498        // {@link checkComponentPermission}.
6499        Identity tlsIdentity = sCallerIdentity.get();
6500        if (tlsIdentity != null) {
6501            uid = tlsIdentity.uid;
6502            pid = tlsIdentity.pid;
6503        }
6504
6505        // Our own process gets to do everything.
6506        if (pid == MY_PID) {
6507            return PackageManager.PERMISSION_GRANTED;
6508        }
6509        synchronized (this) {
6510            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6511                    ? PackageManager.PERMISSION_GRANTED
6512                    : PackageManager.PERMISSION_DENIED;
6513        }
6514    }
6515
6516    /**
6517     * Check if the targetPkg can be granted permission to access uri by
6518     * the callingUid using the given modeFlags.  Throws a security exception
6519     * if callingUid is not allowed to do this.  Returns the uid of the target
6520     * if the URI permission grant should be performed; returns -1 if it is not
6521     * needed (for example targetPkg already has permission to access the URI).
6522     * If you already know the uid of the target, you can supply it in
6523     * lastTargetUid else set that to -1.
6524     */
6525    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6526            final int modeFlags, int lastTargetUid) {
6527        if (!Intent.isAccessUriMode(modeFlags)) {
6528            return -1;
6529        }
6530
6531        if (targetPkg != null) {
6532            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6533                    "Checking grant " + targetPkg + " permission to " + grantUri);
6534        }
6535
6536        final IPackageManager pm = AppGlobals.getPackageManager();
6537
6538        // If this is not a content: uri, we can't do anything with it.
6539        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6540            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6541                    "Can't grant URI permission for non-content URI: " + grantUri);
6542            return -1;
6543        }
6544
6545        final String authority = grantUri.uri.getAuthority();
6546        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6547        if (pi == null) {
6548            Slog.w(TAG, "No content provider found for permission check: " +
6549                    grantUri.uri.toSafeString());
6550            return -1;
6551        }
6552
6553        int targetUid = lastTargetUid;
6554        if (targetUid < 0 && targetPkg != null) {
6555            try {
6556                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6557                if (targetUid < 0) {
6558                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6559                            "Can't grant URI permission no uid for: " + targetPkg);
6560                    return -1;
6561                }
6562            } catch (RemoteException ex) {
6563                return -1;
6564            }
6565        }
6566
6567        if (targetUid >= 0) {
6568            // First...  does the target actually need this permission?
6569            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6570                // No need to grant the target this permission.
6571                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6572                        "Target " + targetPkg + " already has full permission to " + grantUri);
6573                return -1;
6574            }
6575        } else {
6576            // First...  there is no target package, so can anyone access it?
6577            boolean allowed = pi.exported;
6578            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6579                if (pi.readPermission != null) {
6580                    allowed = false;
6581                }
6582            }
6583            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6584                if (pi.writePermission != null) {
6585                    allowed = false;
6586                }
6587            }
6588            if (allowed) {
6589                return -1;
6590            }
6591        }
6592
6593        /* There is a special cross user grant if:
6594         * - The target is on another user.
6595         * - Apps on the current user can access the uri without any uid permissions.
6596         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6597         * grant uri permissions.
6598         */
6599        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6600                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6601                modeFlags, false /*without considering the uid permissions*/);
6602
6603        // Second...  is the provider allowing granting of URI permissions?
6604        if (!specialCrossUserGrant) {
6605            if (!pi.grantUriPermissions) {
6606                throw new SecurityException("Provider " + pi.packageName
6607                        + "/" + pi.name
6608                        + " does not allow granting of Uri permissions (uri "
6609                        + grantUri + ")");
6610            }
6611            if (pi.uriPermissionPatterns != null) {
6612                final int N = pi.uriPermissionPatterns.length;
6613                boolean allowed = false;
6614                for (int i=0; i<N; i++) {
6615                    if (pi.uriPermissionPatterns[i] != null
6616                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6617                        allowed = true;
6618                        break;
6619                    }
6620                }
6621                if (!allowed) {
6622                    throw new SecurityException("Provider " + pi.packageName
6623                            + "/" + pi.name
6624                            + " does not allow granting of permission to path of Uri "
6625                            + grantUri);
6626                }
6627            }
6628        }
6629
6630        // Third...  does the caller itself have permission to access
6631        // this uri?
6632        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6633            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6634                // Require they hold a strong enough Uri permission
6635                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6636                    throw new SecurityException("Uid " + callingUid
6637                            + " does not have permission to uri " + grantUri);
6638                }
6639            }
6640        }
6641        return targetUid;
6642    }
6643
6644    @Override
6645    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6646            final int modeFlags, int userId) {
6647        enforceNotIsolatedCaller("checkGrantUriPermission");
6648        synchronized(this) {
6649            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6650                    new GrantUri(userId, uri, false), modeFlags, -1);
6651        }
6652    }
6653
6654    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6655            final int modeFlags, UriPermissionOwner owner) {
6656        if (!Intent.isAccessUriMode(modeFlags)) {
6657            return;
6658        }
6659
6660        // So here we are: the caller has the assumed permission
6661        // to the uri, and the target doesn't.  Let's now give this to
6662        // the target.
6663
6664        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6665                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6666
6667        final String authority = grantUri.uri.getAuthority();
6668        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6669        if (pi == null) {
6670            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6671            return;
6672        }
6673
6674        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6675            grantUri.prefix = true;
6676        }
6677        final UriPermission perm = findOrCreateUriPermissionLocked(
6678                pi.packageName, targetPkg, targetUid, grantUri);
6679        perm.grantModes(modeFlags, owner);
6680    }
6681
6682    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6683            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6684        if (targetPkg == null) {
6685            throw new NullPointerException("targetPkg");
6686        }
6687        int targetUid;
6688        final IPackageManager pm = AppGlobals.getPackageManager();
6689        try {
6690            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6691        } catch (RemoteException ex) {
6692            return;
6693        }
6694
6695        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6696                targetUid);
6697        if (targetUid < 0) {
6698            return;
6699        }
6700
6701        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6702                owner);
6703    }
6704
6705    static class NeededUriGrants extends ArrayList<GrantUri> {
6706        final String targetPkg;
6707        final int targetUid;
6708        final int flags;
6709
6710        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6711            this.targetPkg = targetPkg;
6712            this.targetUid = targetUid;
6713            this.flags = flags;
6714        }
6715    }
6716
6717    /**
6718     * Like checkGrantUriPermissionLocked, but takes an Intent.
6719     */
6720    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6721            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6722        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6723                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6724                + " clip=" + (intent != null ? intent.getClipData() : null)
6725                + " from " + intent + "; flags=0x"
6726                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6727
6728        if (targetPkg == null) {
6729            throw new NullPointerException("targetPkg");
6730        }
6731
6732        if (intent == null) {
6733            return null;
6734        }
6735        Uri data = intent.getData();
6736        ClipData clip = intent.getClipData();
6737        if (data == null && clip == null) {
6738            return null;
6739        }
6740        // Default userId for uris in the intent (if they don't specify it themselves)
6741        int contentUserHint = intent.getContentUserHint();
6742        if (contentUserHint == UserHandle.USER_CURRENT) {
6743            contentUserHint = UserHandle.getUserId(callingUid);
6744        }
6745        final IPackageManager pm = AppGlobals.getPackageManager();
6746        int targetUid;
6747        if (needed != null) {
6748            targetUid = needed.targetUid;
6749        } else {
6750            try {
6751                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6752            } catch (RemoteException ex) {
6753                return null;
6754            }
6755            if (targetUid < 0) {
6756                if (DEBUG_URI_PERMISSION) {
6757                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6758                            + " on user " + targetUserId);
6759                }
6760                return null;
6761            }
6762        }
6763        if (data != null) {
6764            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6765            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6766                    targetUid);
6767            if (targetUid > 0) {
6768                if (needed == null) {
6769                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6770                }
6771                needed.add(grantUri);
6772            }
6773        }
6774        if (clip != null) {
6775            for (int i=0; i<clip.getItemCount(); i++) {
6776                Uri uri = clip.getItemAt(i).getUri();
6777                if (uri != null) {
6778                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6779                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6780                            targetUid);
6781                    if (targetUid > 0) {
6782                        if (needed == null) {
6783                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6784                        }
6785                        needed.add(grantUri);
6786                    }
6787                } else {
6788                    Intent clipIntent = clip.getItemAt(i).getIntent();
6789                    if (clipIntent != null) {
6790                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6791                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6792                        if (newNeeded != null) {
6793                            needed = newNeeded;
6794                        }
6795                    }
6796                }
6797            }
6798        }
6799
6800        return needed;
6801    }
6802
6803    /**
6804     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6805     */
6806    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6807            UriPermissionOwner owner) {
6808        if (needed != null) {
6809            for (int i=0; i<needed.size(); i++) {
6810                GrantUri grantUri = needed.get(i);
6811                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6812                        grantUri, needed.flags, owner);
6813            }
6814        }
6815    }
6816
6817    void grantUriPermissionFromIntentLocked(int callingUid,
6818            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6819        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6820                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6821        if (needed == null) {
6822            return;
6823        }
6824
6825        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6826    }
6827
6828    @Override
6829    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6830            final int modeFlags, int userId) {
6831        enforceNotIsolatedCaller("grantUriPermission");
6832        GrantUri grantUri = new GrantUri(userId, uri, false);
6833        synchronized(this) {
6834            final ProcessRecord r = getRecordForAppLocked(caller);
6835            if (r == null) {
6836                throw new SecurityException("Unable to find app for caller "
6837                        + caller
6838                        + " when granting permission to uri " + grantUri);
6839            }
6840            if (targetPkg == null) {
6841                throw new IllegalArgumentException("null target");
6842            }
6843            if (grantUri == null) {
6844                throw new IllegalArgumentException("null uri");
6845            }
6846
6847            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6848                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6849                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6850                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6851
6852            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6853                    UserHandle.getUserId(r.uid));
6854        }
6855    }
6856
6857    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6858        if (perm.modeFlags == 0) {
6859            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6860                    perm.targetUid);
6861            if (perms != null) {
6862                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6863                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6864
6865                perms.remove(perm.uri);
6866                if (perms.isEmpty()) {
6867                    mGrantedUriPermissions.remove(perm.targetUid);
6868                }
6869            }
6870        }
6871    }
6872
6873    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6874        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6875
6876        final IPackageManager pm = AppGlobals.getPackageManager();
6877        final String authority = grantUri.uri.getAuthority();
6878        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6879        if (pi == null) {
6880            Slog.w(TAG, "No content provider found for permission revoke: "
6881                    + grantUri.toSafeString());
6882            return;
6883        }
6884
6885        // Does the caller have this permission on the URI?
6886        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6887            // Right now, if you are not the original owner of the permission,
6888            // you are not allowed to revoke it.
6889            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6890                throw new SecurityException("Uid " + callingUid
6891                        + " does not have permission to uri " + grantUri);
6892            //}
6893        }
6894
6895        boolean persistChanged = false;
6896
6897        // Go through all of the permissions and remove any that match.
6898        int N = mGrantedUriPermissions.size();
6899        for (int i = 0; i < N; i++) {
6900            final int targetUid = mGrantedUriPermissions.keyAt(i);
6901            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6902
6903            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6904                final UriPermission perm = it.next();
6905                if (perm.uri.sourceUserId == grantUri.sourceUserId
6906                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6907                    if (DEBUG_URI_PERMISSION)
6908                        Slog.v(TAG,
6909                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6910                    persistChanged |= perm.revokeModes(
6911                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6912                    if (perm.modeFlags == 0) {
6913                        it.remove();
6914                    }
6915                }
6916            }
6917
6918            if (perms.isEmpty()) {
6919                mGrantedUriPermissions.remove(targetUid);
6920                N--;
6921                i--;
6922            }
6923        }
6924
6925        if (persistChanged) {
6926            schedulePersistUriGrants();
6927        }
6928    }
6929
6930    @Override
6931    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6932            int userId) {
6933        enforceNotIsolatedCaller("revokeUriPermission");
6934        synchronized(this) {
6935            final ProcessRecord r = getRecordForAppLocked(caller);
6936            if (r == null) {
6937                throw new SecurityException("Unable to find app for caller "
6938                        + caller
6939                        + " when revoking permission to uri " + uri);
6940            }
6941            if (uri == null) {
6942                Slog.w(TAG, "revokeUriPermission: null uri");
6943                return;
6944            }
6945
6946            if (!Intent.isAccessUriMode(modeFlags)) {
6947                return;
6948            }
6949
6950            final IPackageManager pm = AppGlobals.getPackageManager();
6951            final String authority = uri.getAuthority();
6952            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6953            if (pi == null) {
6954                Slog.w(TAG, "No content provider found for permission revoke: "
6955                        + uri.toSafeString());
6956                return;
6957            }
6958
6959            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6960        }
6961    }
6962
6963    /**
6964     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6965     * given package.
6966     *
6967     * @param packageName Package name to match, or {@code null} to apply to all
6968     *            packages.
6969     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6970     *            to all users.
6971     * @param persistable If persistable grants should be removed.
6972     */
6973    private void removeUriPermissionsForPackageLocked(
6974            String packageName, int userHandle, boolean persistable) {
6975        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6976            throw new IllegalArgumentException("Must narrow by either package or user");
6977        }
6978
6979        boolean persistChanged = false;
6980
6981        int N = mGrantedUriPermissions.size();
6982        for (int i = 0; i < N; i++) {
6983            final int targetUid = mGrantedUriPermissions.keyAt(i);
6984            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6985
6986            // Only inspect grants matching user
6987            if (userHandle == UserHandle.USER_ALL
6988                    || userHandle == UserHandle.getUserId(targetUid)) {
6989                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6990                    final UriPermission perm = it.next();
6991
6992                    // Only inspect grants matching package
6993                    if (packageName == null || perm.sourcePkg.equals(packageName)
6994                            || perm.targetPkg.equals(packageName)) {
6995                        persistChanged |= perm.revokeModes(
6996                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6997
6998                        // Only remove when no modes remain; any persisted grants
6999                        // will keep this alive.
7000                        if (perm.modeFlags == 0) {
7001                            it.remove();
7002                        }
7003                    }
7004                }
7005
7006                if (perms.isEmpty()) {
7007                    mGrantedUriPermissions.remove(targetUid);
7008                    N--;
7009                    i--;
7010                }
7011            }
7012        }
7013
7014        if (persistChanged) {
7015            schedulePersistUriGrants();
7016        }
7017    }
7018
7019    @Override
7020    public IBinder newUriPermissionOwner(String name) {
7021        enforceNotIsolatedCaller("newUriPermissionOwner");
7022        synchronized(this) {
7023            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7024            return owner.getExternalTokenLocked();
7025        }
7026    }
7027
7028    @Override
7029    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7030            final int modeFlags, int sourceUserId, int targetUserId) {
7031        synchronized(this) {
7032            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7033            if (owner == null) {
7034                throw new IllegalArgumentException("Unknown owner: " + token);
7035            }
7036            if (fromUid != Binder.getCallingUid()) {
7037                if (Binder.getCallingUid() != Process.myUid()) {
7038                    // Only system code can grant URI permissions on behalf
7039                    // of other users.
7040                    throw new SecurityException("nice try");
7041                }
7042            }
7043            if (targetPkg == null) {
7044                throw new IllegalArgumentException("null target");
7045            }
7046            if (uri == null) {
7047                throw new IllegalArgumentException("null uri");
7048            }
7049
7050            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7051                    modeFlags, owner, targetUserId);
7052        }
7053    }
7054
7055    @Override
7056    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7057        synchronized(this) {
7058            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7059            if (owner == null) {
7060                throw new IllegalArgumentException("Unknown owner: " + token);
7061            }
7062
7063            if (uri == null) {
7064                owner.removeUriPermissionsLocked(mode);
7065            } else {
7066                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7067            }
7068        }
7069    }
7070
7071    private void schedulePersistUriGrants() {
7072        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7073            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7074                    10 * DateUtils.SECOND_IN_MILLIS);
7075        }
7076    }
7077
7078    private void writeGrantedUriPermissions() {
7079        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7080
7081        // Snapshot permissions so we can persist without lock
7082        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7083        synchronized (this) {
7084            final int size = mGrantedUriPermissions.size();
7085            for (int i = 0; i < size; i++) {
7086                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7087                for (UriPermission perm : perms.values()) {
7088                    if (perm.persistedModeFlags != 0) {
7089                        persist.add(perm.snapshot());
7090                    }
7091                }
7092            }
7093        }
7094
7095        FileOutputStream fos = null;
7096        try {
7097            fos = mGrantFile.startWrite();
7098
7099            XmlSerializer out = new FastXmlSerializer();
7100            out.setOutput(fos, "utf-8");
7101            out.startDocument(null, true);
7102            out.startTag(null, TAG_URI_GRANTS);
7103            for (UriPermission.Snapshot perm : persist) {
7104                out.startTag(null, TAG_URI_GRANT);
7105                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7106                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7107                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7108                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7109                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7110                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7111                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7112                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7113                out.endTag(null, TAG_URI_GRANT);
7114            }
7115            out.endTag(null, TAG_URI_GRANTS);
7116            out.endDocument();
7117
7118            mGrantFile.finishWrite(fos);
7119        } catch (IOException e) {
7120            if (fos != null) {
7121                mGrantFile.failWrite(fos);
7122            }
7123        }
7124    }
7125
7126    private void readGrantedUriPermissionsLocked() {
7127        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7128
7129        final long now = System.currentTimeMillis();
7130
7131        FileInputStream fis = null;
7132        try {
7133            fis = mGrantFile.openRead();
7134            final XmlPullParser in = Xml.newPullParser();
7135            in.setInput(fis, null);
7136
7137            int type;
7138            while ((type = in.next()) != END_DOCUMENT) {
7139                final String tag = in.getName();
7140                if (type == START_TAG) {
7141                    if (TAG_URI_GRANT.equals(tag)) {
7142                        final int sourceUserId;
7143                        final int targetUserId;
7144                        final int userHandle = readIntAttribute(in,
7145                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7146                        if (userHandle != UserHandle.USER_NULL) {
7147                            // For backwards compatibility.
7148                            sourceUserId = userHandle;
7149                            targetUserId = userHandle;
7150                        } else {
7151                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7152                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7153                        }
7154                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7155                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7156                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7157                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7158                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7159                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7160
7161                        // Sanity check that provider still belongs to source package
7162                        final ProviderInfo pi = getProviderInfoLocked(
7163                                uri.getAuthority(), sourceUserId);
7164                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7165                            int targetUid = -1;
7166                            try {
7167                                targetUid = AppGlobals.getPackageManager()
7168                                        .getPackageUid(targetPkg, targetUserId);
7169                            } catch (RemoteException e) {
7170                            }
7171                            if (targetUid != -1) {
7172                                final UriPermission perm = findOrCreateUriPermissionLocked(
7173                                        sourcePkg, targetPkg, targetUid,
7174                                        new GrantUri(sourceUserId, uri, prefix));
7175                                perm.initPersistedModes(modeFlags, createdTime);
7176                            }
7177                        } else {
7178                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7179                                    + " but instead found " + pi);
7180                        }
7181                    }
7182                }
7183            }
7184        } catch (FileNotFoundException e) {
7185            // Missing grants is okay
7186        } catch (IOException e) {
7187            Log.wtf(TAG, "Failed reading Uri grants", e);
7188        } catch (XmlPullParserException e) {
7189            Log.wtf(TAG, "Failed reading Uri grants", e);
7190        } finally {
7191            IoUtils.closeQuietly(fis);
7192        }
7193    }
7194
7195    @Override
7196    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7197        enforceNotIsolatedCaller("takePersistableUriPermission");
7198
7199        Preconditions.checkFlagsArgument(modeFlags,
7200                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7201
7202        synchronized (this) {
7203            final int callingUid = Binder.getCallingUid();
7204            boolean persistChanged = false;
7205            GrantUri grantUri = new GrantUri(userId, uri, false);
7206
7207            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7208                    new GrantUri(userId, uri, false));
7209            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7210                    new GrantUri(userId, uri, true));
7211
7212            final boolean exactValid = (exactPerm != null)
7213                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7214            final boolean prefixValid = (prefixPerm != null)
7215                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7216
7217            if (!(exactValid || prefixValid)) {
7218                throw new SecurityException("No persistable permission grants found for UID "
7219                        + callingUid + " and Uri " + grantUri.toSafeString());
7220            }
7221
7222            if (exactValid) {
7223                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7224            }
7225            if (prefixValid) {
7226                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7227            }
7228
7229            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7230
7231            if (persistChanged) {
7232                schedulePersistUriGrants();
7233            }
7234        }
7235    }
7236
7237    @Override
7238    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7239        enforceNotIsolatedCaller("releasePersistableUriPermission");
7240
7241        Preconditions.checkFlagsArgument(modeFlags,
7242                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7243
7244        synchronized (this) {
7245            final int callingUid = Binder.getCallingUid();
7246            boolean persistChanged = false;
7247
7248            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7249                    new GrantUri(userId, uri, false));
7250            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7251                    new GrantUri(userId, uri, true));
7252            if (exactPerm == null && prefixPerm == null) {
7253                throw new SecurityException("No permission grants found for UID " + callingUid
7254                        + " and Uri " + uri.toSafeString());
7255            }
7256
7257            if (exactPerm != null) {
7258                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7259                removeUriPermissionIfNeededLocked(exactPerm);
7260            }
7261            if (prefixPerm != null) {
7262                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7263                removeUriPermissionIfNeededLocked(prefixPerm);
7264            }
7265
7266            if (persistChanged) {
7267                schedulePersistUriGrants();
7268            }
7269        }
7270    }
7271
7272    /**
7273     * Prune any older {@link UriPermission} for the given UID until outstanding
7274     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7275     *
7276     * @return if any mutations occured that require persisting.
7277     */
7278    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7279        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7280        if (perms == null) return false;
7281        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7282
7283        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7284        for (UriPermission perm : perms.values()) {
7285            if (perm.persistedModeFlags != 0) {
7286                persisted.add(perm);
7287            }
7288        }
7289
7290        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7291        if (trimCount <= 0) return false;
7292
7293        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7294        for (int i = 0; i < trimCount; i++) {
7295            final UriPermission perm = persisted.get(i);
7296
7297            if (DEBUG_URI_PERMISSION) {
7298                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7299            }
7300
7301            perm.releasePersistableModes(~0);
7302            removeUriPermissionIfNeededLocked(perm);
7303        }
7304
7305        return true;
7306    }
7307
7308    @Override
7309    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7310            String packageName, boolean incoming) {
7311        enforceNotIsolatedCaller("getPersistedUriPermissions");
7312        Preconditions.checkNotNull(packageName, "packageName");
7313
7314        final int callingUid = Binder.getCallingUid();
7315        final IPackageManager pm = AppGlobals.getPackageManager();
7316        try {
7317            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7318            if (packageUid != callingUid) {
7319                throw new SecurityException(
7320                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7321            }
7322        } catch (RemoteException e) {
7323            throw new SecurityException("Failed to verify package name ownership");
7324        }
7325
7326        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7327        synchronized (this) {
7328            if (incoming) {
7329                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7330                        callingUid);
7331                if (perms == null) {
7332                    Slog.w(TAG, "No permission grants found for " + packageName);
7333                } else {
7334                    for (UriPermission perm : perms.values()) {
7335                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7336                            result.add(perm.buildPersistedPublicApiObject());
7337                        }
7338                    }
7339                }
7340            } else {
7341                final int size = mGrantedUriPermissions.size();
7342                for (int i = 0; i < size; i++) {
7343                    final ArrayMap<GrantUri, UriPermission> perms =
7344                            mGrantedUriPermissions.valueAt(i);
7345                    for (UriPermission perm : perms.values()) {
7346                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7347                            result.add(perm.buildPersistedPublicApiObject());
7348                        }
7349                    }
7350                }
7351            }
7352        }
7353        return new ParceledListSlice<android.content.UriPermission>(result);
7354    }
7355
7356    @Override
7357    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7358        synchronized (this) {
7359            ProcessRecord app =
7360                who != null ? getRecordForAppLocked(who) : null;
7361            if (app == null) return;
7362
7363            Message msg = Message.obtain();
7364            msg.what = WAIT_FOR_DEBUGGER_MSG;
7365            msg.obj = app;
7366            msg.arg1 = waiting ? 1 : 0;
7367            mHandler.sendMessage(msg);
7368        }
7369    }
7370
7371    @Override
7372    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7373        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7374        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7375        outInfo.availMem = Process.getFreeMemory();
7376        outInfo.totalMem = Process.getTotalMemory();
7377        outInfo.threshold = homeAppMem;
7378        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7379        outInfo.hiddenAppThreshold = cachedAppMem;
7380        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7381                ProcessList.SERVICE_ADJ);
7382        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7383                ProcessList.VISIBLE_APP_ADJ);
7384        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7385                ProcessList.FOREGROUND_APP_ADJ);
7386    }
7387
7388    // =========================================================
7389    // TASK MANAGEMENT
7390    // =========================================================
7391
7392    @Override
7393    public List<IAppTask> getAppTasks() {
7394        final PackageManager pm = mContext.getPackageManager();
7395        int callingUid = Binder.getCallingUid();
7396        long ident = Binder.clearCallingIdentity();
7397
7398        // Compose the list of packages for this id to test against
7399        HashSet<String> packages = new HashSet<String>();
7400        String[] uidPackages = pm.getPackagesForUid(callingUid);
7401        for (int i = 0; i < uidPackages.length; i++) {
7402            packages.add(uidPackages[i]);
7403        }
7404
7405        synchronized(this) {
7406            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7407            try {
7408                if (localLOGV) Slog.v(TAG, "getAppTasks");
7409
7410                final int N = mRecentTasks.size();
7411                for (int i = 0; i < N; i++) {
7412                    TaskRecord tr = mRecentTasks.get(i);
7413                    // Skip tasks that are not created by the caller
7414                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7415                        ActivityManager.RecentTaskInfo taskInfo =
7416                                createRecentTaskInfoFromTaskRecord(tr);
7417                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7418                        list.add(taskImpl);
7419                    }
7420                }
7421            } finally {
7422                Binder.restoreCallingIdentity(ident);
7423            }
7424            return list;
7425        }
7426    }
7427
7428    @Override
7429    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7430        final int callingUid = Binder.getCallingUid();
7431        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7432
7433        synchronized(this) {
7434            if (localLOGV) Slog.v(
7435                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7436
7437            final boolean allowed = checkCallingPermission(
7438                    android.Manifest.permission.GET_TASKS)
7439                    == PackageManager.PERMISSION_GRANTED;
7440            if (!allowed) {
7441                Slog.w(TAG, "getTasks: caller " + callingUid
7442                        + " does not hold GET_TASKS; limiting output");
7443            }
7444
7445            // TODO: Improve with MRU list from all ActivityStacks.
7446            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7447        }
7448
7449        return list;
7450    }
7451
7452    TaskRecord getMostRecentTask() {
7453        return mRecentTasks.get(0);
7454    }
7455
7456    /**
7457     * Creates a new RecentTaskInfo from a TaskRecord.
7458     */
7459    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7460        // Update the task description to reflect any changes in the task stack
7461        tr.updateTaskDescription();
7462
7463        // Compose the recent task info
7464        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7465        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7466        rti.persistentId = tr.taskId;
7467        rti.baseIntent = new Intent(tr.getBaseIntent());
7468        rti.origActivity = tr.origActivity;
7469        rti.description = tr.lastDescription;
7470        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7471        rti.userId = tr.userId;
7472        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7473        rti.firstActiveTime = tr.firstActiveTime;
7474        rti.lastActiveTime = tr.lastActiveTime;
7475        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7476        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
7477        return rti;
7478    }
7479
7480    @Override
7481    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7482        final int callingUid = Binder.getCallingUid();
7483        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7484                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7485
7486        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7487        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7488        synchronized (this) {
7489            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7490                    == PackageManager.PERMISSION_GRANTED;
7491            if (!allowed) {
7492                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7493                        + " does not hold GET_TASKS; limiting output");
7494            }
7495            final boolean detailed = checkCallingPermission(
7496                    android.Manifest.permission.GET_DETAILED_TASKS)
7497                    == PackageManager.PERMISSION_GRANTED;
7498
7499            IPackageManager pm = AppGlobals.getPackageManager();
7500
7501            final int N = mRecentTasks.size();
7502            ArrayList<ActivityManager.RecentTaskInfo> res
7503                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7504                            maxNum < N ? maxNum : N);
7505
7506            final Set<Integer> includedUsers;
7507            if (includeProfiles) {
7508                includedUsers = getProfileIdsLocked(userId);
7509            } else {
7510                includedUsers = new HashSet<Integer>();
7511            }
7512            includedUsers.add(Integer.valueOf(userId));
7513
7514            // Regroup affiliated tasks together.
7515            for (int i = 0; i < N; ) {
7516                TaskRecord task = mRecentTasks.remove(i);
7517                if (mTmpRecents.contains(task)) {
7518                    continue;
7519                }
7520                int affiliatedTaskId = task.mAffiliatedTaskId;
7521                while (true) {
7522                    TaskRecord next = task.mNextAffiliate;
7523                    if (next == null) {
7524                        break;
7525                    }
7526                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7527                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7528                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7529                        task.setNextAffiliate(null);
7530                        if (next.mPrevAffiliate == task) {
7531                            next.setPrevAffiliate(null);
7532                        }
7533                        break;
7534                    }
7535                    if (next.mPrevAffiliate != task) {
7536                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7537                                next.mPrevAffiliate + " task=" + task);
7538                        next.setPrevAffiliate(null);
7539                        break;
7540                    }
7541                    if (!mRecentTasks.contains(next)) {
7542                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7543                        task.setNextAffiliate(null);
7544                        if (next.mPrevAffiliate == task) {
7545                            next.setPrevAffiliate(null);
7546                        }
7547                        break;
7548                    }
7549                    task = next;
7550                }
7551                // task is now the end of the list
7552                do {
7553                    mRecentTasks.remove(task);
7554                    mRecentTasks.add(i++, task);
7555                    mTmpRecents.add(task);
7556                } while ((task = task.mPrevAffiliate) != null);
7557            }
7558            mTmpRecents.clear();
7559            // mRecentTasks is now in sorted, affiliated order.
7560
7561            for (int i=0; i<N && maxNum > 0; i++) {
7562                TaskRecord tr = mRecentTasks.get(i);
7563                // Only add calling user or related users recent tasks
7564                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7565
7566                // Return the entry if desired by the caller.  We always return
7567                // the first entry, because callers always expect this to be the
7568                // foreground app.  We may filter others if the caller has
7569                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7570                // we should exclude the entry.
7571
7572                if (i == 0
7573                        || withExcluded
7574                        || (tr.intent == null)
7575                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7576                                == 0)) {
7577                    if (!allowed) {
7578                        // If the caller doesn't have the GET_TASKS permission, then only
7579                        // allow them to see a small subset of tasks -- their own and home.
7580                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7581                            continue;
7582                        }
7583                    }
7584                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7585                        // Don't include auto remove tasks that are finished or finishing.
7586                        continue;
7587                    }
7588
7589                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7590                    if (!detailed) {
7591                        rti.baseIntent.replaceExtras((Bundle)null);
7592                    }
7593
7594                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7595                        // Check whether this activity is currently available.
7596                        try {
7597                            if (rti.origActivity != null) {
7598                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7599                                        == null) {
7600                                    continue;
7601                                }
7602                            } else if (rti.baseIntent != null) {
7603                                if (pm.queryIntentActivities(rti.baseIntent,
7604                                        null, 0, userId) == null) {
7605                                    continue;
7606                                }
7607                            }
7608                        } catch (RemoteException e) {
7609                            // Will never happen.
7610                        }
7611                    }
7612
7613                    res.add(rti);
7614                    maxNum--;
7615                }
7616            }
7617            return res;
7618        }
7619    }
7620
7621    private TaskRecord recentTaskForIdLocked(int id) {
7622        final int N = mRecentTasks.size();
7623            for (int i=0; i<N; i++) {
7624                TaskRecord tr = mRecentTasks.get(i);
7625                if (tr.taskId == id) {
7626                    return tr;
7627                }
7628            }
7629            return null;
7630    }
7631
7632    @Override
7633    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7634        synchronized (this) {
7635            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7636                    "getTaskThumbnail()");
7637            TaskRecord tr = recentTaskForIdLocked(id);
7638            if (tr != null) {
7639                return tr.getTaskThumbnailLocked();
7640            }
7641        }
7642        return null;
7643    }
7644
7645    @Override
7646    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7647        synchronized (this) {
7648            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7649            if (r != null) {
7650                r.taskDescription = td;
7651                r.task.updateTaskDescription();
7652            }
7653        }
7654    }
7655
7656    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7657        if (!pr.killedByAm) {
7658            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7659            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7660                    pr.processName, pr.setAdj, reason);
7661            pr.killedByAm = true;
7662            Process.killProcessQuiet(pr.pid);
7663            Process.killProcessGroup(pr.info.uid, pr.pid);
7664        }
7665    }
7666
7667    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7668        tr.disposeThumbnail();
7669        mRecentTasks.remove(tr);
7670        tr.closeRecentsChain();
7671        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7672        Intent baseIntent = new Intent(
7673                tr.intent != null ? tr.intent : tr.affinityIntent);
7674        ComponentName component = baseIntent.getComponent();
7675        if (component == null) {
7676            Slog.w(TAG, "Now component for base intent of task: " + tr);
7677            return;
7678        }
7679
7680        // Find any running services associated with this app.
7681        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7682
7683        if (killProcesses) {
7684            // Find any running processes associated with this app.
7685            final String pkg = component.getPackageName();
7686            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7687            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7688            for (int i=0; i<pmap.size(); i++) {
7689                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7690                for (int j=0; j<uids.size(); j++) {
7691                    ProcessRecord proc = uids.valueAt(j);
7692                    if (proc.userId != tr.userId) {
7693                        continue;
7694                    }
7695                    if (!proc.pkgList.containsKey(pkg)) {
7696                        continue;
7697                    }
7698                    procs.add(proc);
7699                }
7700            }
7701
7702            // Kill the running processes.
7703            for (int i=0; i<procs.size(); i++) {
7704                ProcessRecord pr = procs.get(i);
7705                if (pr == mHomeProcess) {
7706                    // Don't kill the home process along with tasks from the same package.
7707                    continue;
7708                }
7709                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7710                    killUnneededProcessLocked(pr, "remove task");
7711                } else {
7712                    pr.waitingToKill = "remove task";
7713                }
7714            }
7715        }
7716    }
7717
7718    /**
7719     * Removes the task with the specified task id.
7720     *
7721     * @param taskId Identifier of the task to be removed.
7722     * @param flags Additional operational flags.  May be 0 or
7723     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7724     * @return Returns true if the given task was found and removed.
7725     */
7726    private boolean removeTaskByIdLocked(int taskId, int flags) {
7727        TaskRecord tr = recentTaskForIdLocked(taskId);
7728        if (tr != null) {
7729            tr.removeTaskActivitiesLocked();
7730            cleanUpRemovedTaskLocked(tr, flags);
7731            if (tr.isPersistable) {
7732                notifyTaskPersisterLocked(null, true);
7733            }
7734            return true;
7735        }
7736        return false;
7737    }
7738
7739    @Override
7740    public boolean removeTask(int taskId, int flags) {
7741        synchronized (this) {
7742            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7743                    "removeTask()");
7744            long ident = Binder.clearCallingIdentity();
7745            try {
7746                return removeTaskByIdLocked(taskId, flags);
7747            } finally {
7748                Binder.restoreCallingIdentity(ident);
7749            }
7750        }
7751    }
7752
7753    /**
7754     * TODO: Add mController hook
7755     */
7756    @Override
7757    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7758        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7759                "moveTaskToFront()");
7760
7761        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7762        synchronized(this) {
7763            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7764                    Binder.getCallingUid(), "Task to front")) {
7765                ActivityOptions.abort(options);
7766                return;
7767            }
7768            final long origId = Binder.clearCallingIdentity();
7769            try {
7770                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7771                if (task == null) {
7772                    return;
7773                }
7774                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7775                    mStackSupervisor.showLockTaskToast();
7776                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7777                    return;
7778                }
7779                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7780                if (prev != null && prev.isRecentsActivity()) {
7781                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7782                }
7783                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7784            } finally {
7785                Binder.restoreCallingIdentity(origId);
7786            }
7787            ActivityOptions.abort(options);
7788        }
7789    }
7790
7791    @Override
7792    public void moveTaskToBack(int taskId) {
7793        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7794                "moveTaskToBack()");
7795
7796        synchronized(this) {
7797            TaskRecord tr = recentTaskForIdLocked(taskId);
7798            if (tr != null) {
7799                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7800                ActivityStack stack = tr.stack;
7801                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7802                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7803                            Binder.getCallingUid(), "Task to back")) {
7804                        return;
7805                    }
7806                }
7807                final long origId = Binder.clearCallingIdentity();
7808                try {
7809                    stack.moveTaskToBackLocked(taskId, null);
7810                } finally {
7811                    Binder.restoreCallingIdentity(origId);
7812                }
7813            }
7814        }
7815    }
7816
7817    /**
7818     * Moves an activity, and all of the other activities within the same task, to the bottom
7819     * of the history stack.  The activity's order within the task is unchanged.
7820     *
7821     * @param token A reference to the activity we wish to move
7822     * @param nonRoot If false then this only works if the activity is the root
7823     *                of a task; if true it will work for any activity in a task.
7824     * @return Returns true if the move completed, false if not.
7825     */
7826    @Override
7827    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7828        enforceNotIsolatedCaller("moveActivityTaskToBack");
7829        synchronized(this) {
7830            final long origId = Binder.clearCallingIdentity();
7831            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7832            if (taskId >= 0) {
7833                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7834            }
7835            Binder.restoreCallingIdentity(origId);
7836        }
7837        return false;
7838    }
7839
7840    @Override
7841    public void moveTaskBackwards(int task) {
7842        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7843                "moveTaskBackwards()");
7844
7845        synchronized(this) {
7846            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7847                    Binder.getCallingUid(), "Task backwards")) {
7848                return;
7849            }
7850            final long origId = Binder.clearCallingIdentity();
7851            moveTaskBackwardsLocked(task);
7852            Binder.restoreCallingIdentity(origId);
7853        }
7854    }
7855
7856    private final void moveTaskBackwardsLocked(int task) {
7857        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7858    }
7859
7860    @Override
7861    public IBinder getHomeActivityToken() throws RemoteException {
7862        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7863                "getHomeActivityToken()");
7864        synchronized (this) {
7865            return mStackSupervisor.getHomeActivityToken();
7866        }
7867    }
7868
7869    @Override
7870    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7871            IActivityContainerCallback callback) throws RemoteException {
7872        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7873                "createActivityContainer()");
7874        synchronized (this) {
7875            if (parentActivityToken == null) {
7876                throw new IllegalArgumentException("parent token must not be null");
7877            }
7878            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7879            if (r == null) {
7880                return null;
7881            }
7882            if (callback == null) {
7883                throw new IllegalArgumentException("callback must not be null");
7884            }
7885            return mStackSupervisor.createActivityContainer(r, callback);
7886        }
7887    }
7888
7889    @Override
7890    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7891        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7892                "deleteActivityContainer()");
7893        synchronized (this) {
7894            mStackSupervisor.deleteActivityContainer(container);
7895        }
7896    }
7897
7898    @Override
7899    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7900            throws RemoteException {
7901        synchronized (this) {
7902            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7903            if (stack != null) {
7904                return stack.mActivityContainer;
7905            }
7906            return null;
7907        }
7908    }
7909
7910    @Override
7911    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7912        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7913                "moveTaskToStack()");
7914        if (stackId == HOME_STACK_ID) {
7915            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7916                    new RuntimeException("here").fillInStackTrace());
7917        }
7918        synchronized (this) {
7919            long ident = Binder.clearCallingIdentity();
7920            try {
7921                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7922                        + stackId + " toTop=" + toTop);
7923                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7924            } finally {
7925                Binder.restoreCallingIdentity(ident);
7926            }
7927        }
7928    }
7929
7930    @Override
7931    public void resizeStack(int stackBoxId, Rect bounds) {
7932        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7933                "resizeStackBox()");
7934        long ident = Binder.clearCallingIdentity();
7935        try {
7936            mWindowManager.resizeStack(stackBoxId, bounds);
7937        } finally {
7938            Binder.restoreCallingIdentity(ident);
7939        }
7940    }
7941
7942    @Override
7943    public List<StackInfo> getAllStackInfos() {
7944        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7945                "getAllStackInfos()");
7946        long ident = Binder.clearCallingIdentity();
7947        try {
7948            synchronized (this) {
7949                return mStackSupervisor.getAllStackInfosLocked();
7950            }
7951        } finally {
7952            Binder.restoreCallingIdentity(ident);
7953        }
7954    }
7955
7956    @Override
7957    public StackInfo getStackInfo(int stackId) {
7958        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7959                "getStackInfo()");
7960        long ident = Binder.clearCallingIdentity();
7961        try {
7962            synchronized (this) {
7963                return mStackSupervisor.getStackInfoLocked(stackId);
7964            }
7965        } finally {
7966            Binder.restoreCallingIdentity(ident);
7967        }
7968    }
7969
7970    @Override
7971    public boolean isInHomeStack(int taskId) {
7972        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7973                "getStackInfo()");
7974        long ident = Binder.clearCallingIdentity();
7975        try {
7976            synchronized (this) {
7977                TaskRecord tr = recentTaskForIdLocked(taskId);
7978                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7979            }
7980        } finally {
7981            Binder.restoreCallingIdentity(ident);
7982        }
7983    }
7984
7985    @Override
7986    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7987        synchronized(this) {
7988            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7989        }
7990    }
7991
7992    private boolean isLockTaskAuthorized(String pkg) {
7993        final DevicePolicyManager dpm = (DevicePolicyManager)
7994                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7995        try {
7996            int uid = mContext.getPackageManager().getPackageUid(pkg,
7997                    Binder.getCallingUserHandle().getIdentifier());
7998            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7999        } catch (NameNotFoundException e) {
8000            return false;
8001        }
8002    }
8003
8004    void startLockTaskMode(TaskRecord task) {
8005        final String pkg;
8006        synchronized (this) {
8007            pkg = task.intent.getComponent().getPackageName();
8008        }
8009        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8010        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8011            final TaskRecord taskRecord = task;
8012            mHandler.post(new Runnable() {
8013                @Override
8014                public void run() {
8015                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8016                }
8017            });
8018            return;
8019        }
8020        long ident = Binder.clearCallingIdentity();
8021        try {
8022            synchronized (this) {
8023                // Since we lost lock on task, make sure it is still there.
8024                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8025                if (task != null) {
8026                    if (!isSystemInitiated
8027                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8028                        throw new IllegalArgumentException("Invalid task, not in foreground");
8029                    }
8030                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8031                }
8032            }
8033        } finally {
8034            Binder.restoreCallingIdentity(ident);
8035        }
8036    }
8037
8038    @Override
8039    public void startLockTaskMode(int taskId) {
8040        final TaskRecord task;
8041        long ident = Binder.clearCallingIdentity();
8042        try {
8043            synchronized (this) {
8044                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8045            }
8046        } finally {
8047            Binder.restoreCallingIdentity(ident);
8048        }
8049        if (task != null) {
8050            startLockTaskMode(task);
8051        }
8052    }
8053
8054    @Override
8055    public void startLockTaskMode(IBinder token) {
8056        final TaskRecord task;
8057        long ident = Binder.clearCallingIdentity();
8058        try {
8059            synchronized (this) {
8060                final ActivityRecord r = ActivityRecord.forToken(token);
8061                if (r == null) {
8062                    return;
8063                }
8064                task = r.task;
8065            }
8066        } finally {
8067            Binder.restoreCallingIdentity(ident);
8068        }
8069        if (task != null) {
8070            startLockTaskMode(task);
8071        }
8072    }
8073
8074    @Override
8075    public void startLockTaskModeOnCurrent() throws RemoteException {
8076        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8077        ActivityRecord r = null;
8078        synchronized (this) {
8079            r = mStackSupervisor.topRunningActivityLocked();
8080        }
8081        startLockTaskMode(r.task);
8082    }
8083
8084    @Override
8085    public void stopLockTaskMode() {
8086        // Verify that the user matches the package of the intent for the TaskRecord
8087        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8088        // and stopLockTaskMode.
8089        final int callingUid = Binder.getCallingUid();
8090        if (callingUid != Process.SYSTEM_UID) {
8091            try {
8092                String pkg =
8093                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8094                int uid = mContext.getPackageManager().getPackageUid(pkg,
8095                        Binder.getCallingUserHandle().getIdentifier());
8096                if (uid != callingUid) {
8097                    throw new SecurityException("Invalid uid, expected " + uid);
8098                }
8099            } catch (NameNotFoundException e) {
8100                Log.d(TAG, "stopLockTaskMode " + e);
8101                return;
8102            }
8103        }
8104        long ident = Binder.clearCallingIdentity();
8105        try {
8106            Log.d(TAG, "stopLockTaskMode");
8107            // Stop lock task
8108            synchronized (this) {
8109                mStackSupervisor.setLockTaskModeLocked(null, false);
8110            }
8111        } finally {
8112            Binder.restoreCallingIdentity(ident);
8113        }
8114    }
8115
8116    @Override
8117    public void stopLockTaskModeOnCurrent() throws RemoteException {
8118        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8119        long ident = Binder.clearCallingIdentity();
8120        try {
8121            stopLockTaskMode();
8122        } finally {
8123            Binder.restoreCallingIdentity(ident);
8124        }
8125    }
8126
8127    @Override
8128    public boolean isInLockTaskMode() {
8129        synchronized (this) {
8130            return mStackSupervisor.isInLockTaskMode();
8131        }
8132    }
8133
8134    // =========================================================
8135    // CONTENT PROVIDERS
8136    // =========================================================
8137
8138    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8139        List<ProviderInfo> providers = null;
8140        try {
8141            providers = AppGlobals.getPackageManager().
8142                queryContentProviders(app.processName, app.uid,
8143                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8144        } catch (RemoteException ex) {
8145        }
8146        if (DEBUG_MU)
8147            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8148        int userId = app.userId;
8149        if (providers != null) {
8150            int N = providers.size();
8151            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8152            for (int i=0; i<N; i++) {
8153                ProviderInfo cpi =
8154                    (ProviderInfo)providers.get(i);
8155                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8156                        cpi.name, cpi.flags);
8157                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8158                    // This is a singleton provider, but a user besides the
8159                    // default user is asking to initialize a process it runs
8160                    // in...  well, no, it doesn't actually run in this process,
8161                    // it runs in the process of the default user.  Get rid of it.
8162                    providers.remove(i);
8163                    N--;
8164                    i--;
8165                    continue;
8166                }
8167
8168                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8169                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8170                if (cpr == null) {
8171                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8172                    mProviderMap.putProviderByClass(comp, cpr);
8173                }
8174                if (DEBUG_MU)
8175                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8176                app.pubProviders.put(cpi.name, cpr);
8177                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8178                    // Don't add this if it is a platform component that is marked
8179                    // to run in multiple processes, because this is actually
8180                    // part of the framework so doesn't make sense to track as a
8181                    // separate apk in the process.
8182                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8183                            mProcessStats);
8184                }
8185                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8186            }
8187        }
8188        return providers;
8189    }
8190
8191    /**
8192     * Check if {@link ProcessRecord} has a possible chance at accessing the
8193     * given {@link ProviderInfo}. Final permission checking is always done
8194     * in {@link ContentProvider}.
8195     */
8196    private final String checkContentProviderPermissionLocked(
8197            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8198        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8199        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8200        boolean checkedGrants = false;
8201        if (checkUser) {
8202            // Looking for cross-user grants before enforcing the typical cross-users permissions
8203            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8204            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8205                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8206                    return null;
8207                }
8208                checkedGrants = true;
8209            }
8210            userId = handleIncomingUser(callingPid, callingUid, userId,
8211                    false, ALLOW_NON_FULL,
8212                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8213            if (userId != tmpTargetUserId) {
8214                // When we actually went to determine the final targer user ID, this ended
8215                // up different than our initial check for the authority.  This is because
8216                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8217                // SELF.  So we need to re-check the grants again.
8218                checkedGrants = false;
8219            }
8220        }
8221        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8222                cpi.applicationInfo.uid, cpi.exported)
8223                == PackageManager.PERMISSION_GRANTED) {
8224            return null;
8225        }
8226        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8227                cpi.applicationInfo.uid, cpi.exported)
8228                == PackageManager.PERMISSION_GRANTED) {
8229            return null;
8230        }
8231
8232        PathPermission[] pps = cpi.pathPermissions;
8233        if (pps != null) {
8234            int i = pps.length;
8235            while (i > 0) {
8236                i--;
8237                PathPermission pp = pps[i];
8238                String pprperm = pp.getReadPermission();
8239                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8240                        cpi.applicationInfo.uid, cpi.exported)
8241                        == PackageManager.PERMISSION_GRANTED) {
8242                    return null;
8243                }
8244                String ppwperm = pp.getWritePermission();
8245                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8246                        cpi.applicationInfo.uid, cpi.exported)
8247                        == PackageManager.PERMISSION_GRANTED) {
8248                    return null;
8249                }
8250            }
8251        }
8252        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8253            return null;
8254        }
8255
8256        String msg;
8257        if (!cpi.exported) {
8258            msg = "Permission Denial: opening provider " + cpi.name
8259                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8260                    + ", uid=" + callingUid + ") that is not exported from uid "
8261                    + cpi.applicationInfo.uid;
8262        } else {
8263            msg = "Permission Denial: opening provider " + cpi.name
8264                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8265                    + ", uid=" + callingUid + ") requires "
8266                    + cpi.readPermission + " or " + cpi.writePermission;
8267        }
8268        Slog.w(TAG, msg);
8269        return msg;
8270    }
8271
8272    /**
8273     * Returns if the ContentProvider has granted a uri to callingUid
8274     */
8275    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8276        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8277        if (perms != null) {
8278            for (int i=perms.size()-1; i>=0; i--) {
8279                GrantUri grantUri = perms.keyAt(i);
8280                if (grantUri.sourceUserId == userId || !checkUser) {
8281                    if (matchesProvider(grantUri.uri, cpi)) {
8282                        return true;
8283                    }
8284                }
8285            }
8286        }
8287        return false;
8288    }
8289
8290    /**
8291     * Returns true if the uri authority is one of the authorities specified in the provider.
8292     */
8293    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8294        String uriAuth = uri.getAuthority();
8295        String cpiAuth = cpi.authority;
8296        if (cpiAuth.indexOf(';') == -1) {
8297            return cpiAuth.equals(uriAuth);
8298        }
8299        String[] cpiAuths = cpiAuth.split(";");
8300        int length = cpiAuths.length;
8301        for (int i = 0; i < length; i++) {
8302            if (cpiAuths[i].equals(uriAuth)) return true;
8303        }
8304        return false;
8305    }
8306
8307    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8308            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8309        if (r != null) {
8310            for (int i=0; i<r.conProviders.size(); i++) {
8311                ContentProviderConnection conn = r.conProviders.get(i);
8312                if (conn.provider == cpr) {
8313                    if (DEBUG_PROVIDER) Slog.v(TAG,
8314                            "Adding provider requested by "
8315                            + r.processName + " from process "
8316                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8317                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8318                    if (stable) {
8319                        conn.stableCount++;
8320                        conn.numStableIncs++;
8321                    } else {
8322                        conn.unstableCount++;
8323                        conn.numUnstableIncs++;
8324                    }
8325                    return conn;
8326                }
8327            }
8328            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8329            if (stable) {
8330                conn.stableCount = 1;
8331                conn.numStableIncs = 1;
8332            } else {
8333                conn.unstableCount = 1;
8334                conn.numUnstableIncs = 1;
8335            }
8336            cpr.connections.add(conn);
8337            r.conProviders.add(conn);
8338            return conn;
8339        }
8340        cpr.addExternalProcessHandleLocked(externalProcessToken);
8341        return null;
8342    }
8343
8344    boolean decProviderCountLocked(ContentProviderConnection conn,
8345            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8346        if (conn != null) {
8347            cpr = conn.provider;
8348            if (DEBUG_PROVIDER) Slog.v(TAG,
8349                    "Removing provider requested by "
8350                    + conn.client.processName + " from process "
8351                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8352                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8353            if (stable) {
8354                conn.stableCount--;
8355            } else {
8356                conn.unstableCount--;
8357            }
8358            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8359                cpr.connections.remove(conn);
8360                conn.client.conProviders.remove(conn);
8361                return true;
8362            }
8363            return false;
8364        }
8365        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8366        return false;
8367    }
8368
8369    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8370            String name, IBinder token, boolean stable, int userId) {
8371        ContentProviderRecord cpr;
8372        ContentProviderConnection conn = null;
8373        ProviderInfo cpi = null;
8374
8375        synchronized(this) {
8376            ProcessRecord r = null;
8377            if (caller != null) {
8378                r = getRecordForAppLocked(caller);
8379                if (r == null) {
8380                    throw new SecurityException(
8381                            "Unable to find app for caller " + caller
8382                          + " (pid=" + Binder.getCallingPid()
8383                          + ") when getting content provider " + name);
8384                }
8385            }
8386
8387            boolean checkCrossUser = true;
8388
8389            // First check if this content provider has been published...
8390            cpr = mProviderMap.getProviderByName(name, userId);
8391            // If that didn't work, check if it exists for user 0 and then
8392            // verify that it's a singleton provider before using it.
8393            if (cpr == null && userId != UserHandle.USER_OWNER) {
8394                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8395                if (cpr != null) {
8396                    cpi = cpr.info;
8397                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8398                            cpi.name, cpi.flags)
8399                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8400                        userId = UserHandle.USER_OWNER;
8401                        checkCrossUser = false;
8402                    } else {
8403                        cpr = null;
8404                        cpi = null;
8405                    }
8406                }
8407            }
8408
8409            boolean providerRunning = cpr != null;
8410            if (providerRunning) {
8411                cpi = cpr.info;
8412                String msg;
8413                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8414                        != null) {
8415                    throw new SecurityException(msg);
8416                }
8417
8418                if (r != null && cpr.canRunHere(r)) {
8419                    // This provider has been published or is in the process
8420                    // of being published...  but it is also allowed to run
8421                    // in the caller's process, so don't make a connection
8422                    // and just let the caller instantiate its own instance.
8423                    ContentProviderHolder holder = cpr.newHolder(null);
8424                    // don't give caller the provider object, it needs
8425                    // to make its own.
8426                    holder.provider = null;
8427                    return holder;
8428                }
8429
8430                final long origId = Binder.clearCallingIdentity();
8431
8432                // In this case the provider instance already exists, so we can
8433                // return it right away.
8434                conn = incProviderCountLocked(r, cpr, token, stable);
8435                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8436                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8437                        // If this is a perceptible app accessing the provider,
8438                        // make sure to count it as being accessed and thus
8439                        // back up on the LRU list.  This is good because
8440                        // content providers are often expensive to start.
8441                        updateLruProcessLocked(cpr.proc, false, null);
8442                    }
8443                }
8444
8445                if (cpr.proc != null) {
8446                    if (false) {
8447                        if (cpr.name.flattenToShortString().equals(
8448                                "com.android.providers.calendar/.CalendarProvider2")) {
8449                            Slog.v(TAG, "****************** KILLING "
8450                                + cpr.name.flattenToShortString());
8451                            Process.killProcess(cpr.proc.pid);
8452                        }
8453                    }
8454                    boolean success = updateOomAdjLocked(cpr.proc);
8455                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8456                    // NOTE: there is still a race here where a signal could be
8457                    // pending on the process even though we managed to update its
8458                    // adj level.  Not sure what to do about this, but at least
8459                    // the race is now smaller.
8460                    if (!success) {
8461                        // Uh oh...  it looks like the provider's process
8462                        // has been killed on us.  We need to wait for a new
8463                        // process to be started, and make sure its death
8464                        // doesn't kill our process.
8465                        Slog.i(TAG,
8466                                "Existing provider " + cpr.name.flattenToShortString()
8467                                + " is crashing; detaching " + r);
8468                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8469                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8470                        if (!lastRef) {
8471                            // This wasn't the last ref our process had on
8472                            // the provider...  we have now been killed, bail.
8473                            return null;
8474                        }
8475                        providerRunning = false;
8476                        conn = null;
8477                    }
8478                }
8479
8480                Binder.restoreCallingIdentity(origId);
8481            }
8482
8483            boolean singleton;
8484            if (!providerRunning) {
8485                try {
8486                    cpi = AppGlobals.getPackageManager().
8487                        resolveContentProvider(name,
8488                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8489                } catch (RemoteException ex) {
8490                }
8491                if (cpi == null) {
8492                    return null;
8493                }
8494                // If the provider is a singleton AND
8495                // (it's a call within the same user || the provider is a
8496                // privileged app)
8497                // Then allow connecting to the singleton provider
8498                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8499                        cpi.name, cpi.flags)
8500                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8501                if (singleton) {
8502                    userId = UserHandle.USER_OWNER;
8503                }
8504                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8505
8506                String msg;
8507                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8508                        != null) {
8509                    throw new SecurityException(msg);
8510                }
8511
8512                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8513                        && !cpi.processName.equals("system")) {
8514                    // If this content provider does not run in the system
8515                    // process, and the system is not yet ready to run other
8516                    // processes, then fail fast instead of hanging.
8517                    throw new IllegalArgumentException(
8518                            "Attempt to launch content provider before system ready");
8519                }
8520
8521                // Make sure that the user who owns this provider is started.  If not,
8522                // we don't want to allow it to run.
8523                if (mStartedUsers.get(userId) == null) {
8524                    Slog.w(TAG, "Unable to launch app "
8525                            + cpi.applicationInfo.packageName + "/"
8526                            + cpi.applicationInfo.uid + " for provider "
8527                            + name + ": user " + userId + " is stopped");
8528                    return null;
8529                }
8530
8531                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8532                cpr = mProviderMap.getProviderByClass(comp, userId);
8533                final boolean firstClass = cpr == null;
8534                if (firstClass) {
8535                    try {
8536                        ApplicationInfo ai =
8537                            AppGlobals.getPackageManager().
8538                                getApplicationInfo(
8539                                        cpi.applicationInfo.packageName,
8540                                        STOCK_PM_FLAGS, userId);
8541                        if (ai == null) {
8542                            Slog.w(TAG, "No package info for content provider "
8543                                    + cpi.name);
8544                            return null;
8545                        }
8546                        ai = getAppInfoForUser(ai, userId);
8547                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8548                    } catch (RemoteException ex) {
8549                        // pm is in same process, this will never happen.
8550                    }
8551                }
8552
8553                if (r != null && cpr.canRunHere(r)) {
8554                    // If this is a multiprocess provider, then just return its
8555                    // info and allow the caller to instantiate it.  Only do
8556                    // this if the provider is the same user as the caller's
8557                    // process, or can run as root (so can be in any process).
8558                    return cpr.newHolder(null);
8559                }
8560
8561                if (DEBUG_PROVIDER) {
8562                    RuntimeException e = new RuntimeException("here");
8563                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8564                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8565                }
8566
8567                // This is single process, and our app is now connecting to it.
8568                // See if we are already in the process of launching this
8569                // provider.
8570                final int N = mLaunchingProviders.size();
8571                int i;
8572                for (i=0; i<N; i++) {
8573                    if (mLaunchingProviders.get(i) == cpr) {
8574                        break;
8575                    }
8576                }
8577
8578                // If the provider is not already being launched, then get it
8579                // started.
8580                if (i >= N) {
8581                    final long origId = Binder.clearCallingIdentity();
8582
8583                    try {
8584                        // Content provider is now in use, its package can't be stopped.
8585                        try {
8586                            AppGlobals.getPackageManager().setPackageStoppedState(
8587                                    cpr.appInfo.packageName, false, userId);
8588                        } catch (RemoteException e) {
8589                        } catch (IllegalArgumentException e) {
8590                            Slog.w(TAG, "Failed trying to unstop package "
8591                                    + cpr.appInfo.packageName + ": " + e);
8592                        }
8593
8594                        // Use existing process if already started
8595                        ProcessRecord proc = getProcessRecordLocked(
8596                                cpi.processName, cpr.appInfo.uid, false);
8597                        if (proc != null && proc.thread != null) {
8598                            if (DEBUG_PROVIDER) {
8599                                Slog.d(TAG, "Installing in existing process " + proc);
8600                            }
8601                            proc.pubProviders.put(cpi.name, cpr);
8602                            try {
8603                                proc.thread.scheduleInstallProvider(cpi);
8604                            } catch (RemoteException e) {
8605                            }
8606                        } else {
8607                            proc = startProcessLocked(cpi.processName,
8608                                    cpr.appInfo, false, 0, "content provider",
8609                                    new ComponentName(cpi.applicationInfo.packageName,
8610                                            cpi.name), false, false, false);
8611                            if (proc == null) {
8612                                Slog.w(TAG, "Unable to launch app "
8613                                        + cpi.applicationInfo.packageName + "/"
8614                                        + cpi.applicationInfo.uid + " for provider "
8615                                        + name + ": process is bad");
8616                                return null;
8617                            }
8618                        }
8619                        cpr.launchingApp = proc;
8620                        mLaunchingProviders.add(cpr);
8621                    } finally {
8622                        Binder.restoreCallingIdentity(origId);
8623                    }
8624                }
8625
8626                // Make sure the provider is published (the same provider class
8627                // may be published under multiple names).
8628                if (firstClass) {
8629                    mProviderMap.putProviderByClass(comp, cpr);
8630                }
8631
8632                mProviderMap.putProviderByName(name, cpr);
8633                conn = incProviderCountLocked(r, cpr, token, stable);
8634                if (conn != null) {
8635                    conn.waiting = true;
8636                }
8637            }
8638        }
8639
8640        // Wait for the provider to be published...
8641        synchronized (cpr) {
8642            while (cpr.provider == null) {
8643                if (cpr.launchingApp == null) {
8644                    Slog.w(TAG, "Unable to launch app "
8645                            + cpi.applicationInfo.packageName + "/"
8646                            + cpi.applicationInfo.uid + " for provider "
8647                            + name + ": launching app became null");
8648                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8649                            UserHandle.getUserId(cpi.applicationInfo.uid),
8650                            cpi.applicationInfo.packageName,
8651                            cpi.applicationInfo.uid, name);
8652                    return null;
8653                }
8654                try {
8655                    if (DEBUG_MU) {
8656                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8657                                + cpr.launchingApp);
8658                    }
8659                    if (conn != null) {
8660                        conn.waiting = true;
8661                    }
8662                    cpr.wait();
8663                } catch (InterruptedException ex) {
8664                } finally {
8665                    if (conn != null) {
8666                        conn.waiting = false;
8667                    }
8668                }
8669            }
8670        }
8671        return cpr != null ? cpr.newHolder(conn) : null;
8672    }
8673
8674    @Override
8675    public final ContentProviderHolder getContentProvider(
8676            IApplicationThread caller, String name, int userId, boolean stable) {
8677        enforceNotIsolatedCaller("getContentProvider");
8678        if (caller == null) {
8679            String msg = "null IApplicationThread when getting content provider "
8680                    + name;
8681            Slog.w(TAG, msg);
8682            throw new SecurityException(msg);
8683        }
8684        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8685        // with cross-user grant.
8686        return getContentProviderImpl(caller, name, null, stable, userId);
8687    }
8688
8689    public ContentProviderHolder getContentProviderExternal(
8690            String name, int userId, IBinder token) {
8691        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8692            "Do not have permission in call getContentProviderExternal()");
8693        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8694                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8695        return getContentProviderExternalUnchecked(name, token, userId);
8696    }
8697
8698    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8699            IBinder token, int userId) {
8700        return getContentProviderImpl(null, name, token, true, userId);
8701    }
8702
8703    /**
8704     * Drop a content provider from a ProcessRecord's bookkeeping
8705     */
8706    public void removeContentProvider(IBinder connection, boolean stable) {
8707        enforceNotIsolatedCaller("removeContentProvider");
8708        long ident = Binder.clearCallingIdentity();
8709        try {
8710            synchronized (this) {
8711                ContentProviderConnection conn;
8712                try {
8713                    conn = (ContentProviderConnection)connection;
8714                } catch (ClassCastException e) {
8715                    String msg ="removeContentProvider: " + connection
8716                            + " not a ContentProviderConnection";
8717                    Slog.w(TAG, msg);
8718                    throw new IllegalArgumentException(msg);
8719                }
8720                if (conn == null) {
8721                    throw new NullPointerException("connection is null");
8722                }
8723                if (decProviderCountLocked(conn, null, null, stable)) {
8724                    updateOomAdjLocked();
8725                }
8726            }
8727        } finally {
8728            Binder.restoreCallingIdentity(ident);
8729        }
8730    }
8731
8732    public void removeContentProviderExternal(String name, IBinder token) {
8733        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8734            "Do not have permission in call removeContentProviderExternal()");
8735        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8736    }
8737
8738    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8739        synchronized (this) {
8740            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8741            if(cpr == null) {
8742                //remove from mProvidersByClass
8743                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8744                return;
8745            }
8746
8747            //update content provider record entry info
8748            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8749            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8750            if (localCpr.hasExternalProcessHandles()) {
8751                if (localCpr.removeExternalProcessHandleLocked(token)) {
8752                    updateOomAdjLocked();
8753                } else {
8754                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8755                            + " with no external reference for token: "
8756                            + token + ".");
8757                }
8758            } else {
8759                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8760                        + " with no external references.");
8761            }
8762        }
8763    }
8764
8765    public final void publishContentProviders(IApplicationThread caller,
8766            List<ContentProviderHolder> providers) {
8767        if (providers == null) {
8768            return;
8769        }
8770
8771        enforceNotIsolatedCaller("publishContentProviders");
8772        synchronized (this) {
8773            final ProcessRecord r = getRecordForAppLocked(caller);
8774            if (DEBUG_MU)
8775                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8776            if (r == null) {
8777                throw new SecurityException(
8778                        "Unable to find app for caller " + caller
8779                      + " (pid=" + Binder.getCallingPid()
8780                      + ") when publishing content providers");
8781            }
8782
8783            final long origId = Binder.clearCallingIdentity();
8784
8785            final int N = providers.size();
8786            for (int i=0; i<N; i++) {
8787                ContentProviderHolder src = providers.get(i);
8788                if (src == null || src.info == null || src.provider == null) {
8789                    continue;
8790                }
8791                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8792                if (DEBUG_MU)
8793                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8794                if (dst != null) {
8795                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8796                    mProviderMap.putProviderByClass(comp, dst);
8797                    String names[] = dst.info.authority.split(";");
8798                    for (int j = 0; j < names.length; j++) {
8799                        mProviderMap.putProviderByName(names[j], dst);
8800                    }
8801
8802                    int NL = mLaunchingProviders.size();
8803                    int j;
8804                    for (j=0; j<NL; j++) {
8805                        if (mLaunchingProviders.get(j) == dst) {
8806                            mLaunchingProviders.remove(j);
8807                            j--;
8808                            NL--;
8809                        }
8810                    }
8811                    synchronized (dst) {
8812                        dst.provider = src.provider;
8813                        dst.proc = r;
8814                        dst.notifyAll();
8815                    }
8816                    updateOomAdjLocked(r);
8817                }
8818            }
8819
8820            Binder.restoreCallingIdentity(origId);
8821        }
8822    }
8823
8824    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8825        ContentProviderConnection conn;
8826        try {
8827            conn = (ContentProviderConnection)connection;
8828        } catch (ClassCastException e) {
8829            String msg ="refContentProvider: " + connection
8830                    + " not a ContentProviderConnection";
8831            Slog.w(TAG, msg);
8832            throw new IllegalArgumentException(msg);
8833        }
8834        if (conn == null) {
8835            throw new NullPointerException("connection is null");
8836        }
8837
8838        synchronized (this) {
8839            if (stable > 0) {
8840                conn.numStableIncs += stable;
8841            }
8842            stable = conn.stableCount + stable;
8843            if (stable < 0) {
8844                throw new IllegalStateException("stableCount < 0: " + stable);
8845            }
8846
8847            if (unstable > 0) {
8848                conn.numUnstableIncs += unstable;
8849            }
8850            unstable = conn.unstableCount + unstable;
8851            if (unstable < 0) {
8852                throw new IllegalStateException("unstableCount < 0: " + unstable);
8853            }
8854
8855            if ((stable+unstable) <= 0) {
8856                throw new IllegalStateException("ref counts can't go to zero here: stable="
8857                        + stable + " unstable=" + unstable);
8858            }
8859            conn.stableCount = stable;
8860            conn.unstableCount = unstable;
8861            return !conn.dead;
8862        }
8863    }
8864
8865    public void unstableProviderDied(IBinder connection) {
8866        ContentProviderConnection conn;
8867        try {
8868            conn = (ContentProviderConnection)connection;
8869        } catch (ClassCastException e) {
8870            String msg ="refContentProvider: " + connection
8871                    + " not a ContentProviderConnection";
8872            Slog.w(TAG, msg);
8873            throw new IllegalArgumentException(msg);
8874        }
8875        if (conn == null) {
8876            throw new NullPointerException("connection is null");
8877        }
8878
8879        // Safely retrieve the content provider associated with the connection.
8880        IContentProvider provider;
8881        synchronized (this) {
8882            provider = conn.provider.provider;
8883        }
8884
8885        if (provider == null) {
8886            // Um, yeah, we're way ahead of you.
8887            return;
8888        }
8889
8890        // Make sure the caller is being honest with us.
8891        if (provider.asBinder().pingBinder()) {
8892            // Er, no, still looks good to us.
8893            synchronized (this) {
8894                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8895                        + " says " + conn + " died, but we don't agree");
8896                return;
8897            }
8898        }
8899
8900        // Well look at that!  It's dead!
8901        synchronized (this) {
8902            if (conn.provider.provider != provider) {
8903                // But something changed...  good enough.
8904                return;
8905            }
8906
8907            ProcessRecord proc = conn.provider.proc;
8908            if (proc == null || proc.thread == null) {
8909                // Seems like the process is already cleaned up.
8910                return;
8911            }
8912
8913            // As far as we're concerned, this is just like receiving a
8914            // death notification...  just a bit prematurely.
8915            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8916                    + ") early provider death");
8917            final long ident = Binder.clearCallingIdentity();
8918            try {
8919                appDiedLocked(proc, proc.pid, proc.thread);
8920            } finally {
8921                Binder.restoreCallingIdentity(ident);
8922            }
8923        }
8924    }
8925
8926    @Override
8927    public void appNotRespondingViaProvider(IBinder connection) {
8928        enforceCallingPermission(
8929                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8930
8931        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8932        if (conn == null) {
8933            Slog.w(TAG, "ContentProviderConnection is null");
8934            return;
8935        }
8936
8937        final ProcessRecord host = conn.provider.proc;
8938        if (host == null) {
8939            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8940            return;
8941        }
8942
8943        final long token = Binder.clearCallingIdentity();
8944        try {
8945            appNotResponding(host, null, null, false, "ContentProvider not responding");
8946        } finally {
8947            Binder.restoreCallingIdentity(token);
8948        }
8949    }
8950
8951    public final void installSystemProviders() {
8952        List<ProviderInfo> providers;
8953        synchronized (this) {
8954            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8955            providers = generateApplicationProvidersLocked(app);
8956            if (providers != null) {
8957                for (int i=providers.size()-1; i>=0; i--) {
8958                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8959                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8960                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8961                                + ": not system .apk");
8962                        providers.remove(i);
8963                    }
8964                }
8965            }
8966        }
8967        if (providers != null) {
8968            mSystemThread.installSystemProviders(providers);
8969        }
8970
8971        mCoreSettingsObserver = new CoreSettingsObserver(this);
8972
8973        //mUsageStatsService.monitorPackages();
8974    }
8975
8976    /**
8977     * Allows apps to retrieve the MIME type of a URI.
8978     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
8979     * users, then it does not need permission to access the ContentProvider.
8980     * Either, it needs cross-user uri grants.
8981     *
8982     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8983     *
8984     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8985     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8986     */
8987    public String getProviderMimeType(Uri uri, int userId) {
8988        enforceNotIsolatedCaller("getProviderMimeType");
8989        final String name = uri.getAuthority();
8990        int callingUid = Binder.getCallingUid();
8991        int callingPid = Binder.getCallingPid();
8992        long ident = 0;
8993        boolean clearedIdentity = false;
8994        userId = unsafeConvertIncomingUser(userId);
8995        if (UserHandle.getUserId(callingUid) != userId) {
8996            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
8997                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
8998                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
8999                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9000                clearedIdentity = true;
9001                ident = Binder.clearCallingIdentity();
9002            }
9003        }
9004        ContentProviderHolder holder = null;
9005        try {
9006            holder = getContentProviderExternalUnchecked(name, null, userId);
9007            if (holder != null) {
9008                return holder.provider.getType(uri);
9009            }
9010        } catch (RemoteException e) {
9011            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9012            return null;
9013        } finally {
9014            // We need to clear the identity to call removeContentProviderExternalUnchecked
9015            if (!clearedIdentity) {
9016                ident = Binder.clearCallingIdentity();
9017            }
9018            try {
9019                if (holder != null) {
9020                    removeContentProviderExternalUnchecked(name, null, userId);
9021                }
9022            } finally {
9023                Binder.restoreCallingIdentity(ident);
9024            }
9025        }
9026
9027        return null;
9028    }
9029
9030    // =========================================================
9031    // GLOBAL MANAGEMENT
9032    // =========================================================
9033
9034    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9035            boolean isolated, int isolatedUid) {
9036        String proc = customProcess != null ? customProcess : info.processName;
9037        BatteryStatsImpl.Uid.Proc ps = null;
9038        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9039        int uid = info.uid;
9040        if (isolated) {
9041            if (isolatedUid == 0) {
9042                int userId = UserHandle.getUserId(uid);
9043                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9044                while (true) {
9045                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9046                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9047                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9048                    }
9049                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9050                    mNextIsolatedProcessUid++;
9051                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9052                        // No process for this uid, use it.
9053                        break;
9054                    }
9055                    stepsLeft--;
9056                    if (stepsLeft <= 0) {
9057                        return null;
9058                    }
9059                }
9060            } else {
9061                // Special case for startIsolatedProcess (internal only), where
9062                // the uid of the isolated process is specified by the caller.
9063                uid = isolatedUid;
9064            }
9065        }
9066        return new ProcessRecord(stats, info, proc, uid);
9067    }
9068
9069    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9070            String abiOverride) {
9071        ProcessRecord app;
9072        if (!isolated) {
9073            app = getProcessRecordLocked(info.processName, info.uid, true);
9074        } else {
9075            app = null;
9076        }
9077
9078        if (app == null) {
9079            app = newProcessRecordLocked(info, null, isolated, 0);
9080            mProcessNames.put(info.processName, app.uid, app);
9081            if (isolated) {
9082                mIsolatedProcesses.put(app.uid, app);
9083            }
9084            updateLruProcessLocked(app, false, null);
9085            updateOomAdjLocked();
9086        }
9087
9088        // This package really, really can not be stopped.
9089        try {
9090            AppGlobals.getPackageManager().setPackageStoppedState(
9091                    info.packageName, false, UserHandle.getUserId(app.uid));
9092        } catch (RemoteException e) {
9093        } catch (IllegalArgumentException e) {
9094            Slog.w(TAG, "Failed trying to unstop package "
9095                    + info.packageName + ": " + e);
9096        }
9097
9098        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9099                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9100            app.persistent = true;
9101            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9102        }
9103        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9104            mPersistentStartingProcesses.add(app);
9105            startProcessLocked(app, "added application", app.processName, abiOverride,
9106                    null /* entryPoint */, null /* entryPointArgs */);
9107        }
9108
9109        return app;
9110    }
9111
9112    public void unhandledBack() {
9113        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9114                "unhandledBack()");
9115
9116        synchronized(this) {
9117            final long origId = Binder.clearCallingIdentity();
9118            try {
9119                getFocusedStack().unhandledBackLocked();
9120            } finally {
9121                Binder.restoreCallingIdentity(origId);
9122            }
9123        }
9124    }
9125
9126    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9127        enforceNotIsolatedCaller("openContentUri");
9128        final int userId = UserHandle.getCallingUserId();
9129        String name = uri.getAuthority();
9130        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9131        ParcelFileDescriptor pfd = null;
9132        if (cph != null) {
9133            // We record the binder invoker's uid in thread-local storage before
9134            // going to the content provider to open the file.  Later, in the code
9135            // that handles all permissions checks, we look for this uid and use
9136            // that rather than the Activity Manager's own uid.  The effect is that
9137            // we do the check against the caller's permissions even though it looks
9138            // to the content provider like the Activity Manager itself is making
9139            // the request.
9140            sCallerIdentity.set(new Identity(
9141                    Binder.getCallingPid(), Binder.getCallingUid()));
9142            try {
9143                pfd = cph.provider.openFile(null, uri, "r", null);
9144            } catch (FileNotFoundException e) {
9145                // do nothing; pfd will be returned null
9146            } finally {
9147                // Ensure that whatever happens, we clean up the identity state
9148                sCallerIdentity.remove();
9149            }
9150
9151            // We've got the fd now, so we're done with the provider.
9152            removeContentProviderExternalUnchecked(name, null, userId);
9153        } else {
9154            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9155        }
9156        return pfd;
9157    }
9158
9159    // Actually is sleeping or shutting down or whatever else in the future
9160    // is an inactive state.
9161    public boolean isSleepingOrShuttingDown() {
9162        return mSleeping || mShuttingDown;
9163    }
9164
9165    public boolean isSleeping() {
9166        return mSleeping;
9167    }
9168
9169    void goingToSleep() {
9170        synchronized(this) {
9171            mWentToSleep = true;
9172            updateEventDispatchingLocked();
9173            goToSleepIfNeededLocked();
9174        }
9175    }
9176
9177    void finishRunningVoiceLocked() {
9178        if (mRunningVoice) {
9179            mRunningVoice = false;
9180            goToSleepIfNeededLocked();
9181        }
9182    }
9183
9184    void goToSleepIfNeededLocked() {
9185        if (mWentToSleep && !mRunningVoice) {
9186            if (!mSleeping) {
9187                mSleeping = true;
9188                mStackSupervisor.goingToSleepLocked();
9189
9190                // Initialize the wake times of all processes.
9191                checkExcessivePowerUsageLocked(false);
9192                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9193                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9194                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9195            }
9196        }
9197    }
9198
9199    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9200        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9201            // Never persist the home stack.
9202            return;
9203        }
9204        mTaskPersister.wakeup(task, flush);
9205    }
9206
9207    @Override
9208    public boolean shutdown(int timeout) {
9209        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9210                != PackageManager.PERMISSION_GRANTED) {
9211            throw new SecurityException("Requires permission "
9212                    + android.Manifest.permission.SHUTDOWN);
9213        }
9214
9215        boolean timedout = false;
9216
9217        synchronized(this) {
9218            mShuttingDown = true;
9219            updateEventDispatchingLocked();
9220            timedout = mStackSupervisor.shutdownLocked(timeout);
9221        }
9222
9223        mAppOpsService.shutdown();
9224        if (mUsageStatsService != null) {
9225            mUsageStatsService.prepareShutdown();
9226        }
9227        mBatteryStatsService.shutdown();
9228        synchronized (this) {
9229            mProcessStats.shutdownLocked();
9230        }
9231        notifyTaskPersisterLocked(null, true);
9232
9233        return timedout;
9234    }
9235
9236    public final void activitySlept(IBinder token) {
9237        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9238
9239        final long origId = Binder.clearCallingIdentity();
9240
9241        synchronized (this) {
9242            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9243            if (r != null) {
9244                mStackSupervisor.activitySleptLocked(r);
9245            }
9246        }
9247
9248        Binder.restoreCallingIdentity(origId);
9249    }
9250
9251    void logLockScreen(String msg) {
9252        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9253                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9254                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9255                mStackSupervisor.mDismissKeyguardOnNextActivity);
9256    }
9257
9258    private void comeOutOfSleepIfNeededLocked() {
9259        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9260            if (mSleeping) {
9261                mSleeping = false;
9262                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9263            }
9264        }
9265    }
9266
9267    void wakingUp() {
9268        synchronized(this) {
9269            mWentToSleep = false;
9270            updateEventDispatchingLocked();
9271            comeOutOfSleepIfNeededLocked();
9272        }
9273    }
9274
9275    void startRunningVoiceLocked() {
9276        if (!mRunningVoice) {
9277            mRunningVoice = true;
9278            comeOutOfSleepIfNeededLocked();
9279        }
9280    }
9281
9282    private void updateEventDispatchingLocked() {
9283        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9284    }
9285
9286    public void setLockScreenShown(boolean shown) {
9287        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9288                != PackageManager.PERMISSION_GRANTED) {
9289            throw new SecurityException("Requires permission "
9290                    + android.Manifest.permission.DEVICE_POWER);
9291        }
9292
9293        synchronized(this) {
9294            long ident = Binder.clearCallingIdentity();
9295            try {
9296                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9297                mLockScreenShown = shown;
9298                comeOutOfSleepIfNeededLocked();
9299            } finally {
9300                Binder.restoreCallingIdentity(ident);
9301            }
9302        }
9303    }
9304
9305    @Override
9306    public void stopAppSwitches() {
9307        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9308                != PackageManager.PERMISSION_GRANTED) {
9309            throw new SecurityException("Requires permission "
9310                    + android.Manifest.permission.STOP_APP_SWITCHES);
9311        }
9312
9313        synchronized(this) {
9314            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9315                    + APP_SWITCH_DELAY_TIME;
9316            mDidAppSwitch = false;
9317            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9318            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9319            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9320        }
9321    }
9322
9323    public void resumeAppSwitches() {
9324        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9325                != PackageManager.PERMISSION_GRANTED) {
9326            throw new SecurityException("Requires permission "
9327                    + android.Manifest.permission.STOP_APP_SWITCHES);
9328        }
9329
9330        synchronized(this) {
9331            // Note that we don't execute any pending app switches... we will
9332            // let those wait until either the timeout, or the next start
9333            // activity request.
9334            mAppSwitchesAllowedTime = 0;
9335        }
9336    }
9337
9338    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9339            String name) {
9340        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9341            return true;
9342        }
9343
9344        final int perm = checkComponentPermission(
9345                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9346                callingUid, -1, true);
9347        if (perm == PackageManager.PERMISSION_GRANTED) {
9348            return true;
9349        }
9350
9351        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9352        return false;
9353    }
9354
9355    public void setDebugApp(String packageName, boolean waitForDebugger,
9356            boolean persistent) {
9357        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9358                "setDebugApp()");
9359
9360        long ident = Binder.clearCallingIdentity();
9361        try {
9362            // Note that this is not really thread safe if there are multiple
9363            // callers into it at the same time, but that's not a situation we
9364            // care about.
9365            if (persistent) {
9366                final ContentResolver resolver = mContext.getContentResolver();
9367                Settings.Global.putString(
9368                    resolver, Settings.Global.DEBUG_APP,
9369                    packageName);
9370                Settings.Global.putInt(
9371                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9372                    waitForDebugger ? 1 : 0);
9373            }
9374
9375            synchronized (this) {
9376                if (!persistent) {
9377                    mOrigDebugApp = mDebugApp;
9378                    mOrigWaitForDebugger = mWaitForDebugger;
9379                }
9380                mDebugApp = packageName;
9381                mWaitForDebugger = waitForDebugger;
9382                mDebugTransient = !persistent;
9383                if (packageName != null) {
9384                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9385                            false, UserHandle.USER_ALL, "set debug app");
9386                }
9387            }
9388        } finally {
9389            Binder.restoreCallingIdentity(ident);
9390        }
9391    }
9392
9393    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9394        synchronized (this) {
9395            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9396            if (!isDebuggable) {
9397                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9398                    throw new SecurityException("Process not debuggable: " + app.packageName);
9399                }
9400            }
9401
9402            mOpenGlTraceApp = processName;
9403        }
9404    }
9405
9406    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9407            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9408        synchronized (this) {
9409            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9410            if (!isDebuggable) {
9411                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9412                    throw new SecurityException("Process not debuggable: " + app.packageName);
9413                }
9414            }
9415            mProfileApp = processName;
9416            mProfileFile = profileFile;
9417            if (mProfileFd != null) {
9418                try {
9419                    mProfileFd.close();
9420                } catch (IOException e) {
9421                }
9422                mProfileFd = null;
9423            }
9424            mProfileFd = profileFd;
9425            mProfileType = 0;
9426            mAutoStopProfiler = autoStopProfiler;
9427        }
9428    }
9429
9430    @Override
9431    public void setAlwaysFinish(boolean enabled) {
9432        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9433                "setAlwaysFinish()");
9434
9435        Settings.Global.putInt(
9436                mContext.getContentResolver(),
9437                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9438
9439        synchronized (this) {
9440            mAlwaysFinishActivities = enabled;
9441        }
9442    }
9443
9444    @Override
9445    public void setActivityController(IActivityController controller) {
9446        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9447                "setActivityController()");
9448        synchronized (this) {
9449            mController = controller;
9450            Watchdog.getInstance().setActivityController(controller);
9451        }
9452    }
9453
9454    @Override
9455    public void setUserIsMonkey(boolean userIsMonkey) {
9456        synchronized (this) {
9457            synchronized (mPidsSelfLocked) {
9458                final int callingPid = Binder.getCallingPid();
9459                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9460                if (precessRecord == null) {
9461                    throw new SecurityException("Unknown process: " + callingPid);
9462                }
9463                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9464                    throw new SecurityException("Only an instrumentation process "
9465                            + "with a UiAutomation can call setUserIsMonkey");
9466                }
9467            }
9468            mUserIsMonkey = userIsMonkey;
9469        }
9470    }
9471
9472    @Override
9473    public boolean isUserAMonkey() {
9474        synchronized (this) {
9475            // If there is a controller also implies the user is a monkey.
9476            return (mUserIsMonkey || mController != null);
9477        }
9478    }
9479
9480    public void requestBugReport() {
9481        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9482        SystemProperties.set("ctl.start", "bugreport");
9483    }
9484
9485    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9486        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9487    }
9488
9489    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9490        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9491            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9492        }
9493        return KEY_DISPATCHING_TIMEOUT;
9494    }
9495
9496    @Override
9497    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9498        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9499                != PackageManager.PERMISSION_GRANTED) {
9500            throw new SecurityException("Requires permission "
9501                    + android.Manifest.permission.FILTER_EVENTS);
9502        }
9503        ProcessRecord proc;
9504        long timeout;
9505        synchronized (this) {
9506            synchronized (mPidsSelfLocked) {
9507                proc = mPidsSelfLocked.get(pid);
9508            }
9509            timeout = getInputDispatchingTimeoutLocked(proc);
9510        }
9511
9512        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9513            return -1;
9514        }
9515
9516        return timeout;
9517    }
9518
9519    /**
9520     * Handle input dispatching timeouts.
9521     * Returns whether input dispatching should be aborted or not.
9522     */
9523    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9524            final ActivityRecord activity, final ActivityRecord parent,
9525            final boolean aboveSystem, String reason) {
9526        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9527                != PackageManager.PERMISSION_GRANTED) {
9528            throw new SecurityException("Requires permission "
9529                    + android.Manifest.permission.FILTER_EVENTS);
9530        }
9531
9532        final String annotation;
9533        if (reason == null) {
9534            annotation = "Input dispatching timed out";
9535        } else {
9536            annotation = "Input dispatching timed out (" + reason + ")";
9537        }
9538
9539        if (proc != null) {
9540            synchronized (this) {
9541                if (proc.debugging) {
9542                    return false;
9543                }
9544
9545                if (mDidDexOpt) {
9546                    // Give more time since we were dexopting.
9547                    mDidDexOpt = false;
9548                    return false;
9549                }
9550
9551                if (proc.instrumentationClass != null) {
9552                    Bundle info = new Bundle();
9553                    info.putString("shortMsg", "keyDispatchingTimedOut");
9554                    info.putString("longMsg", annotation);
9555                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9556                    return true;
9557                }
9558            }
9559            mHandler.post(new Runnable() {
9560                @Override
9561                public void run() {
9562                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9563                }
9564            });
9565        }
9566
9567        return true;
9568    }
9569
9570    public Bundle getAssistContextExtras(int requestType) {
9571        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9572                "getAssistContextExtras()");
9573        PendingAssistExtras pae;
9574        Bundle extras = new Bundle();
9575        synchronized (this) {
9576            ActivityRecord activity = getFocusedStack().mResumedActivity;
9577            if (activity == null) {
9578                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9579                return null;
9580            }
9581            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9582            if (activity.app == null || activity.app.thread == null) {
9583                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9584                return extras;
9585            }
9586            if (activity.app.pid == Binder.getCallingPid()) {
9587                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9588                return extras;
9589            }
9590            pae = new PendingAssistExtras(activity);
9591            try {
9592                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9593                        requestType);
9594                mPendingAssistExtras.add(pae);
9595                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9596            } catch (RemoteException e) {
9597                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9598                return extras;
9599            }
9600        }
9601        synchronized (pae) {
9602            while (!pae.haveResult) {
9603                try {
9604                    pae.wait();
9605                } catch (InterruptedException e) {
9606                }
9607            }
9608            if (pae.result != null) {
9609                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9610            }
9611        }
9612        synchronized (this) {
9613            mPendingAssistExtras.remove(pae);
9614            mHandler.removeCallbacks(pae);
9615        }
9616        return extras;
9617    }
9618
9619    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9620        PendingAssistExtras pae = (PendingAssistExtras)token;
9621        synchronized (pae) {
9622            pae.result = extras;
9623            pae.haveResult = true;
9624            pae.notifyAll();
9625        }
9626    }
9627
9628    public void registerProcessObserver(IProcessObserver observer) {
9629        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9630                "registerProcessObserver()");
9631        synchronized (this) {
9632            mProcessObservers.register(observer);
9633        }
9634    }
9635
9636    @Override
9637    public void unregisterProcessObserver(IProcessObserver observer) {
9638        synchronized (this) {
9639            mProcessObservers.unregister(observer);
9640        }
9641    }
9642
9643    @Override
9644    public boolean convertFromTranslucent(IBinder token) {
9645        final long origId = Binder.clearCallingIdentity();
9646        try {
9647            synchronized (this) {
9648                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9649                if (r == null) {
9650                    return false;
9651                }
9652                if (r.changeWindowTranslucency(true)) {
9653                    mWindowManager.setAppFullscreen(token, true);
9654                    r.task.stack.releaseMediaResources();
9655                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9656                    return true;
9657                }
9658                return false;
9659            }
9660        } finally {
9661            Binder.restoreCallingIdentity(origId);
9662        }
9663    }
9664
9665    @Override
9666    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9667        final long origId = Binder.clearCallingIdentity();
9668        try {
9669            synchronized (this) {
9670                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9671                if (r == null) {
9672                    return false;
9673                }
9674                int index = r.task.mActivities.lastIndexOf(r);
9675                if (index > 0) {
9676                    ActivityRecord under = r.task.mActivities.get(index - 1);
9677                    under.returningOptions = options;
9678                }
9679                if (r.changeWindowTranslucency(false)) {
9680                    r.task.stack.convertToTranslucent(r);
9681                    mWindowManager.setAppFullscreen(token, false);
9682                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9683                    return true;
9684                } else {
9685                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9686                    return false;
9687                }
9688            }
9689        } finally {
9690            Binder.restoreCallingIdentity(origId);
9691        }
9692    }
9693
9694    @Override
9695    public boolean setMediaPlaying(IBinder token, boolean playing) {
9696        final long origId = Binder.clearCallingIdentity();
9697        try {
9698            synchronized (this) {
9699                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9700                if (r != null) {
9701                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9702                }
9703            }
9704            return false;
9705        } finally {
9706            Binder.restoreCallingIdentity(origId);
9707        }
9708    }
9709
9710    @Override
9711    public boolean isBackgroundMediaPlaying(IBinder token) {
9712        final long origId = Binder.clearCallingIdentity();
9713        try {
9714            synchronized (this) {
9715                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9716                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9717                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9718                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9719                return playing;
9720            }
9721        } finally {
9722            Binder.restoreCallingIdentity(origId);
9723        }
9724    }
9725
9726    @Override
9727    public ActivityOptions getActivityOptions(IBinder token) {
9728        final long origId = Binder.clearCallingIdentity();
9729        try {
9730            synchronized (this) {
9731                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9732                if (r != null) {
9733                    final ActivityOptions activityOptions = r.pendingOptions;
9734                    r.pendingOptions = null;
9735                    return activityOptions;
9736                }
9737                return null;
9738            }
9739        } finally {
9740            Binder.restoreCallingIdentity(origId);
9741        }
9742    }
9743
9744    @Override
9745    public void setImmersive(IBinder token, boolean immersive) {
9746        synchronized(this) {
9747            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9748            if (r == null) {
9749                throw new IllegalArgumentException();
9750            }
9751            r.immersive = immersive;
9752
9753            // update associated state if we're frontmost
9754            if (r == mFocusedActivity) {
9755                if (DEBUG_IMMERSIVE) {
9756                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9757                }
9758                applyUpdateLockStateLocked(r);
9759            }
9760        }
9761    }
9762
9763    @Override
9764    public boolean isImmersive(IBinder token) {
9765        synchronized (this) {
9766            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9767            if (r == null) {
9768                throw new IllegalArgumentException();
9769            }
9770            return r.immersive;
9771        }
9772    }
9773
9774    public boolean isTopActivityImmersive() {
9775        enforceNotIsolatedCaller("startActivity");
9776        synchronized (this) {
9777            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9778            return (r != null) ? r.immersive : false;
9779        }
9780    }
9781
9782    @Override
9783    public boolean isTopOfTask(IBinder token) {
9784        synchronized (this) {
9785            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9786            if (r == null) {
9787                throw new IllegalArgumentException();
9788            }
9789            return r.task.getTopActivity() == r;
9790        }
9791    }
9792
9793    public final void enterSafeMode() {
9794        synchronized(this) {
9795            // It only makes sense to do this before the system is ready
9796            // and started launching other packages.
9797            if (!mSystemReady) {
9798                try {
9799                    AppGlobals.getPackageManager().enterSafeMode();
9800                } catch (RemoteException e) {
9801                }
9802            }
9803
9804            mSafeMode = true;
9805        }
9806    }
9807
9808    public final void showSafeModeOverlay() {
9809        View v = LayoutInflater.from(mContext).inflate(
9810                com.android.internal.R.layout.safe_mode, null);
9811        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9812        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9813        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9814        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9815        lp.gravity = Gravity.BOTTOM | Gravity.START;
9816        lp.format = v.getBackground().getOpacity();
9817        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9818                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9819        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9820        ((WindowManager)mContext.getSystemService(
9821                Context.WINDOW_SERVICE)).addView(v, lp);
9822    }
9823
9824    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9825        if (!(sender instanceof PendingIntentRecord)) {
9826            return;
9827        }
9828        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9829        synchronized (stats) {
9830            if (mBatteryStatsService.isOnBattery()) {
9831                mBatteryStatsService.enforceCallingPermission();
9832                PendingIntentRecord rec = (PendingIntentRecord)sender;
9833                int MY_UID = Binder.getCallingUid();
9834                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9835                BatteryStatsImpl.Uid.Pkg pkg =
9836                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9837                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9838                pkg.incWakeupsLocked();
9839            }
9840        }
9841    }
9842
9843    public boolean killPids(int[] pids, String pReason, boolean secure) {
9844        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9845            throw new SecurityException("killPids only available to the system");
9846        }
9847        String reason = (pReason == null) ? "Unknown" : pReason;
9848        // XXX Note: don't acquire main activity lock here, because the window
9849        // manager calls in with its locks held.
9850
9851        boolean killed = false;
9852        synchronized (mPidsSelfLocked) {
9853            int[] types = new int[pids.length];
9854            int worstType = 0;
9855            for (int i=0; i<pids.length; i++) {
9856                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9857                if (proc != null) {
9858                    int type = proc.setAdj;
9859                    types[i] = type;
9860                    if (type > worstType) {
9861                        worstType = type;
9862                    }
9863                }
9864            }
9865
9866            // If the worst oom_adj is somewhere in the cached proc LRU range,
9867            // then constrain it so we will kill all cached procs.
9868            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9869                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9870                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9871            }
9872
9873            // If this is not a secure call, don't let it kill processes that
9874            // are important.
9875            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9876                worstType = ProcessList.SERVICE_ADJ;
9877            }
9878
9879            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9880            for (int i=0; i<pids.length; i++) {
9881                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9882                if (proc == null) {
9883                    continue;
9884                }
9885                int adj = proc.setAdj;
9886                if (adj >= worstType && !proc.killedByAm) {
9887                    killUnneededProcessLocked(proc, reason);
9888                    killed = true;
9889                }
9890            }
9891        }
9892        return killed;
9893    }
9894
9895    @Override
9896    public void killUid(int uid, String reason) {
9897        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9898            throw new SecurityException("killUid only available to the system");
9899        }
9900        synchronized (this) {
9901            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9902                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9903                    reason != null ? reason : "kill uid");
9904        }
9905    }
9906
9907    @Override
9908    public boolean killProcessesBelowForeground(String reason) {
9909        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9910            throw new SecurityException("killProcessesBelowForeground() only available to system");
9911        }
9912
9913        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9914    }
9915
9916    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9917        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9918            throw new SecurityException("killProcessesBelowAdj() only available to system");
9919        }
9920
9921        boolean killed = false;
9922        synchronized (mPidsSelfLocked) {
9923            final int size = mPidsSelfLocked.size();
9924            for (int i = 0; i < size; i++) {
9925                final int pid = mPidsSelfLocked.keyAt(i);
9926                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9927                if (proc == null) continue;
9928
9929                final int adj = proc.setAdj;
9930                if (adj > belowAdj && !proc.killedByAm) {
9931                    killUnneededProcessLocked(proc, reason);
9932                    killed = true;
9933                }
9934            }
9935        }
9936        return killed;
9937    }
9938
9939    @Override
9940    public void hang(final IBinder who, boolean allowRestart) {
9941        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9942                != PackageManager.PERMISSION_GRANTED) {
9943            throw new SecurityException("Requires permission "
9944                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9945        }
9946
9947        final IBinder.DeathRecipient death = new DeathRecipient() {
9948            @Override
9949            public void binderDied() {
9950                synchronized (this) {
9951                    notifyAll();
9952                }
9953            }
9954        };
9955
9956        try {
9957            who.linkToDeath(death, 0);
9958        } catch (RemoteException e) {
9959            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9960            return;
9961        }
9962
9963        synchronized (this) {
9964            Watchdog.getInstance().setAllowRestart(allowRestart);
9965            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9966            synchronized (death) {
9967                while (who.isBinderAlive()) {
9968                    try {
9969                        death.wait();
9970                    } catch (InterruptedException e) {
9971                    }
9972                }
9973            }
9974            Watchdog.getInstance().setAllowRestart(true);
9975        }
9976    }
9977
9978    @Override
9979    public void restart() {
9980        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9981                != PackageManager.PERMISSION_GRANTED) {
9982            throw new SecurityException("Requires permission "
9983                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9984        }
9985
9986        Log.i(TAG, "Sending shutdown broadcast...");
9987
9988        BroadcastReceiver br = new BroadcastReceiver() {
9989            @Override public void onReceive(Context context, Intent intent) {
9990                // Now the broadcast is done, finish up the low-level shutdown.
9991                Log.i(TAG, "Shutting down activity manager...");
9992                shutdown(10000);
9993                Log.i(TAG, "Shutdown complete, restarting!");
9994                Process.killProcess(Process.myPid());
9995                System.exit(10);
9996            }
9997        };
9998
9999        // First send the high-level shut down broadcast.
10000        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10001        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10002        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10003        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10004        mContext.sendOrderedBroadcastAsUser(intent,
10005                UserHandle.ALL, null, br, mHandler, 0, null, null);
10006        */
10007        br.onReceive(mContext, intent);
10008    }
10009
10010    private long getLowRamTimeSinceIdle(long now) {
10011        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10012    }
10013
10014    @Override
10015    public void performIdleMaintenance() {
10016        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10017                != PackageManager.PERMISSION_GRANTED) {
10018            throw new SecurityException("Requires permission "
10019                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10020        }
10021
10022        synchronized (this) {
10023            final long now = SystemClock.uptimeMillis();
10024            final long timeSinceLastIdle = now - mLastIdleTime;
10025            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10026            mLastIdleTime = now;
10027            mLowRamTimeSinceLastIdle = 0;
10028            if (mLowRamStartTime != 0) {
10029                mLowRamStartTime = now;
10030            }
10031
10032            StringBuilder sb = new StringBuilder(128);
10033            sb.append("Idle maintenance over ");
10034            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10035            sb.append(" low RAM for ");
10036            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10037            Slog.i(TAG, sb.toString());
10038
10039            // If at least 1/3 of our time since the last idle period has been spent
10040            // with RAM low, then we want to kill processes.
10041            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10042
10043            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10044                ProcessRecord proc = mLruProcesses.get(i);
10045                if (proc.notCachedSinceIdle) {
10046                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10047                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10048                        if (doKilling && proc.initialIdlePss != 0
10049                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10050                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
10051                                    + " from " + proc.initialIdlePss + ")");
10052                        }
10053                    }
10054                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10055                    proc.notCachedSinceIdle = true;
10056                    proc.initialIdlePss = 0;
10057                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10058                            isSleeping(), now);
10059                }
10060            }
10061
10062            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10063            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10064        }
10065    }
10066
10067    private void retrieveSettings() {
10068        final ContentResolver resolver = mContext.getContentResolver();
10069        String debugApp = Settings.Global.getString(
10070            resolver, Settings.Global.DEBUG_APP);
10071        boolean waitForDebugger = Settings.Global.getInt(
10072            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10073        boolean alwaysFinishActivities = Settings.Global.getInt(
10074            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10075        boolean forceRtl = Settings.Global.getInt(
10076                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10077        // Transfer any global setting for forcing RTL layout, into a System Property
10078        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10079
10080        Configuration configuration = new Configuration();
10081        Settings.System.getConfiguration(resolver, configuration);
10082        if (forceRtl) {
10083            // This will take care of setting the correct layout direction flags
10084            configuration.setLayoutDirection(configuration.locale);
10085        }
10086
10087        synchronized (this) {
10088            mDebugApp = mOrigDebugApp = debugApp;
10089            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10090            mAlwaysFinishActivities = alwaysFinishActivities;
10091            // This happens before any activities are started, so we can
10092            // change mConfiguration in-place.
10093            updateConfigurationLocked(configuration, null, false, true);
10094            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10095        }
10096    }
10097
10098    public boolean testIsSystemReady() {
10099        // no need to synchronize(this) just to read & return the value
10100        return mSystemReady;
10101    }
10102
10103    private static File getCalledPreBootReceiversFile() {
10104        File dataDir = Environment.getDataDirectory();
10105        File systemDir = new File(dataDir, "system");
10106        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10107        return fname;
10108    }
10109
10110    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10111        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10112        File file = getCalledPreBootReceiversFile();
10113        FileInputStream fis = null;
10114        try {
10115            fis = new FileInputStream(file);
10116            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10117            int fvers = dis.readInt();
10118            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10119                String vers = dis.readUTF();
10120                String codename = dis.readUTF();
10121                String build = dis.readUTF();
10122                if (android.os.Build.VERSION.RELEASE.equals(vers)
10123                        && android.os.Build.VERSION.CODENAME.equals(codename)
10124                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10125                    int num = dis.readInt();
10126                    while (num > 0) {
10127                        num--;
10128                        String pkg = dis.readUTF();
10129                        String cls = dis.readUTF();
10130                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10131                    }
10132                }
10133            }
10134        } catch (FileNotFoundException e) {
10135        } catch (IOException e) {
10136            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10137        } finally {
10138            if (fis != null) {
10139                try {
10140                    fis.close();
10141                } catch (IOException e) {
10142                }
10143            }
10144        }
10145        return lastDoneReceivers;
10146    }
10147
10148    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10149        File file = getCalledPreBootReceiversFile();
10150        FileOutputStream fos = null;
10151        DataOutputStream dos = null;
10152        try {
10153            fos = new FileOutputStream(file);
10154            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10155            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10156            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10157            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10158            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10159            dos.writeInt(list.size());
10160            for (int i=0; i<list.size(); i++) {
10161                dos.writeUTF(list.get(i).getPackageName());
10162                dos.writeUTF(list.get(i).getClassName());
10163            }
10164        } catch (IOException e) {
10165            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10166            file.delete();
10167        } finally {
10168            FileUtils.sync(fos);
10169            if (dos != null) {
10170                try {
10171                    dos.close();
10172                } catch (IOException e) {
10173                    // TODO Auto-generated catch block
10174                    e.printStackTrace();
10175                }
10176            }
10177        }
10178    }
10179
10180    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10181            ArrayList<ComponentName> doneReceivers, int userId) {
10182        boolean waitingUpdate = false;
10183        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10184        List<ResolveInfo> ris = null;
10185        try {
10186            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10187                    intent, null, 0, userId);
10188        } catch (RemoteException e) {
10189        }
10190        if (ris != null) {
10191            for (int i=ris.size()-1; i>=0; i--) {
10192                if ((ris.get(i).activityInfo.applicationInfo.flags
10193                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10194                    ris.remove(i);
10195                }
10196            }
10197            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10198
10199            // For User 0, load the version number. When delivering to a new user, deliver
10200            // to all receivers.
10201            if (userId == UserHandle.USER_OWNER) {
10202                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10203                for (int i=0; i<ris.size(); i++) {
10204                    ActivityInfo ai = ris.get(i).activityInfo;
10205                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10206                    if (lastDoneReceivers.contains(comp)) {
10207                        // We already did the pre boot receiver for this app with the current
10208                        // platform version, so don't do it again...
10209                        ris.remove(i);
10210                        i--;
10211                        // ...however, do keep it as one that has been done, so we don't
10212                        // forget about it when rewriting the file of last done receivers.
10213                        doneReceivers.add(comp);
10214                    }
10215                }
10216            }
10217
10218            // If primary user, send broadcast to all available users, else just to userId
10219            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10220                    : new int[] { userId };
10221            for (int i = 0; i < ris.size(); i++) {
10222                ActivityInfo ai = ris.get(i).activityInfo;
10223                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10224                doneReceivers.add(comp);
10225                intent.setComponent(comp);
10226                for (int j=0; j<users.length; j++) {
10227                    IIntentReceiver finisher = null;
10228                    // On last receiver and user, set up a completion callback
10229                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10230                        finisher = new IIntentReceiver.Stub() {
10231                            public void performReceive(Intent intent, int resultCode,
10232                                    String data, Bundle extras, boolean ordered,
10233                                    boolean sticky, int sendingUser) {
10234                                // The raw IIntentReceiver interface is called
10235                                // with the AM lock held, so redispatch to
10236                                // execute our code without the lock.
10237                                mHandler.post(onFinishCallback);
10238                            }
10239                        };
10240                    }
10241                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10242                            + " for user " + users[j]);
10243                    broadcastIntentLocked(null, null, intent, null, finisher,
10244                            0, null, null, null, AppOpsManager.OP_NONE,
10245                            true, false, MY_PID, Process.SYSTEM_UID,
10246                            users[j]);
10247                    if (finisher != null) {
10248                        waitingUpdate = true;
10249                    }
10250                }
10251            }
10252        }
10253
10254        return waitingUpdate;
10255    }
10256
10257    public void systemReady(final Runnable goingCallback) {
10258        synchronized(this) {
10259            if (mSystemReady) {
10260                // If we're done calling all the receivers, run the next "boot phase" passed in
10261                // by the SystemServer
10262                if (goingCallback != null) {
10263                    goingCallback.run();
10264                }
10265                return;
10266            }
10267
10268            // Make sure we have the current profile info, since it is needed for
10269            // security checks.
10270            updateCurrentProfileIdsLocked();
10271
10272            if (mRecentTasks == null) {
10273                mRecentTasks = mTaskPersister.restoreTasksLocked();
10274                if (!mRecentTasks.isEmpty()) {
10275                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10276                }
10277                mTaskPersister.startPersisting();
10278            }
10279
10280            // Check to see if there are any update receivers to run.
10281            if (!mDidUpdate) {
10282                if (mWaitingUpdate) {
10283                    return;
10284                }
10285                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10286                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10287                    public void run() {
10288                        synchronized (ActivityManagerService.this) {
10289                            mDidUpdate = true;
10290                        }
10291                        writeLastDonePreBootReceivers(doneReceivers);
10292                        showBootMessage(mContext.getText(
10293                                R.string.android_upgrading_complete),
10294                                false);
10295                        systemReady(goingCallback);
10296                    }
10297                }, doneReceivers, UserHandle.USER_OWNER);
10298
10299                if (mWaitingUpdate) {
10300                    return;
10301                }
10302                mDidUpdate = true;
10303            }
10304
10305            mAppOpsService.systemReady();
10306            mSystemReady = true;
10307        }
10308
10309        ArrayList<ProcessRecord> procsToKill = null;
10310        synchronized(mPidsSelfLocked) {
10311            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10312                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10313                if (!isAllowedWhileBooting(proc.info)){
10314                    if (procsToKill == null) {
10315                        procsToKill = new ArrayList<ProcessRecord>();
10316                    }
10317                    procsToKill.add(proc);
10318                }
10319            }
10320        }
10321
10322        synchronized(this) {
10323            if (procsToKill != null) {
10324                for (int i=procsToKill.size()-1; i>=0; i--) {
10325                    ProcessRecord proc = procsToKill.get(i);
10326                    Slog.i(TAG, "Removing system update proc: " + proc);
10327                    removeProcessLocked(proc, true, false, "system update done");
10328                }
10329            }
10330
10331            // Now that we have cleaned up any update processes, we
10332            // are ready to start launching real processes and know that
10333            // we won't trample on them any more.
10334            mProcessesReady = true;
10335        }
10336
10337        Slog.i(TAG, "System now ready");
10338        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10339            SystemClock.uptimeMillis());
10340
10341        synchronized(this) {
10342            // Make sure we have no pre-ready processes sitting around.
10343
10344            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10345                ResolveInfo ri = mContext.getPackageManager()
10346                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10347                                STOCK_PM_FLAGS);
10348                CharSequence errorMsg = null;
10349                if (ri != null) {
10350                    ActivityInfo ai = ri.activityInfo;
10351                    ApplicationInfo app = ai.applicationInfo;
10352                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10353                        mTopAction = Intent.ACTION_FACTORY_TEST;
10354                        mTopData = null;
10355                        mTopComponent = new ComponentName(app.packageName,
10356                                ai.name);
10357                    } else {
10358                        errorMsg = mContext.getResources().getText(
10359                                com.android.internal.R.string.factorytest_not_system);
10360                    }
10361                } else {
10362                    errorMsg = mContext.getResources().getText(
10363                            com.android.internal.R.string.factorytest_no_action);
10364                }
10365                if (errorMsg != null) {
10366                    mTopAction = null;
10367                    mTopData = null;
10368                    mTopComponent = null;
10369                    Message msg = Message.obtain();
10370                    msg.what = SHOW_FACTORY_ERROR_MSG;
10371                    msg.getData().putCharSequence("msg", errorMsg);
10372                    mHandler.sendMessage(msg);
10373                }
10374            }
10375        }
10376
10377        retrieveSettings();
10378
10379        synchronized (this) {
10380            readGrantedUriPermissionsLocked();
10381        }
10382
10383        if (goingCallback != null) goingCallback.run();
10384
10385        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10386                Integer.toString(mCurrentUserId), mCurrentUserId);
10387        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10388                Integer.toString(mCurrentUserId), mCurrentUserId);
10389        mSystemServiceManager.startUser(mCurrentUserId);
10390
10391        synchronized (this) {
10392            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10393                try {
10394                    List apps = AppGlobals.getPackageManager().
10395                        getPersistentApplications(STOCK_PM_FLAGS);
10396                    if (apps != null) {
10397                        int N = apps.size();
10398                        int i;
10399                        for (i=0; i<N; i++) {
10400                            ApplicationInfo info
10401                                = (ApplicationInfo)apps.get(i);
10402                            if (info != null &&
10403                                    !info.packageName.equals("android")) {
10404                                addAppLocked(info, false, null /* ABI override */);
10405                            }
10406                        }
10407                    }
10408                } catch (RemoteException ex) {
10409                    // pm is in same process, this will never happen.
10410                }
10411            }
10412
10413            // Start up initial activity.
10414            mBooting = true;
10415
10416            try {
10417                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10418                    Message msg = Message.obtain();
10419                    msg.what = SHOW_UID_ERROR_MSG;
10420                    mHandler.sendMessage(msg);
10421                }
10422            } catch (RemoteException e) {
10423            }
10424
10425            long ident = Binder.clearCallingIdentity();
10426            try {
10427                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10428                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10429                        | Intent.FLAG_RECEIVER_FOREGROUND);
10430                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10431                broadcastIntentLocked(null, null, intent,
10432                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10433                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10434                intent = new Intent(Intent.ACTION_USER_STARTING);
10435                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10436                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10437                broadcastIntentLocked(null, null, intent,
10438                        null, new IIntentReceiver.Stub() {
10439                            @Override
10440                            public void performReceive(Intent intent, int resultCode, String data,
10441                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10442                                    throws RemoteException {
10443                            }
10444                        }, 0, null, null,
10445                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10446                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10447            } catch (Throwable t) {
10448                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10449            } finally {
10450                Binder.restoreCallingIdentity(ident);
10451            }
10452            mStackSupervisor.resumeTopActivitiesLocked();
10453            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10454        }
10455    }
10456
10457    private boolean makeAppCrashingLocked(ProcessRecord app,
10458            String shortMsg, String longMsg, String stackTrace) {
10459        app.crashing = true;
10460        app.crashingReport = generateProcessError(app,
10461                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10462        startAppProblemLocked(app);
10463        app.stopFreezingAllLocked();
10464        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10465    }
10466
10467    private void makeAppNotRespondingLocked(ProcessRecord app,
10468            String activity, String shortMsg, String longMsg) {
10469        app.notResponding = true;
10470        app.notRespondingReport = generateProcessError(app,
10471                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10472                activity, shortMsg, longMsg, null);
10473        startAppProblemLocked(app);
10474        app.stopFreezingAllLocked();
10475    }
10476
10477    /**
10478     * Generate a process error record, suitable for attachment to a ProcessRecord.
10479     *
10480     * @param app The ProcessRecord in which the error occurred.
10481     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10482     *                      ActivityManager.AppErrorStateInfo
10483     * @param activity The activity associated with the crash, if known.
10484     * @param shortMsg Short message describing the crash.
10485     * @param longMsg Long message describing the crash.
10486     * @param stackTrace Full crash stack trace, may be null.
10487     *
10488     * @return Returns a fully-formed AppErrorStateInfo record.
10489     */
10490    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10491            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10492        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10493
10494        report.condition = condition;
10495        report.processName = app.processName;
10496        report.pid = app.pid;
10497        report.uid = app.info.uid;
10498        report.tag = activity;
10499        report.shortMsg = shortMsg;
10500        report.longMsg = longMsg;
10501        report.stackTrace = stackTrace;
10502
10503        return report;
10504    }
10505
10506    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10507        synchronized (this) {
10508            app.crashing = false;
10509            app.crashingReport = null;
10510            app.notResponding = false;
10511            app.notRespondingReport = null;
10512            if (app.anrDialog == fromDialog) {
10513                app.anrDialog = null;
10514            }
10515            if (app.waitDialog == fromDialog) {
10516                app.waitDialog = null;
10517            }
10518            if (app.pid > 0 && app.pid != MY_PID) {
10519                handleAppCrashLocked(app, null, null, null);
10520                killUnneededProcessLocked(app, "user request after error");
10521            }
10522        }
10523    }
10524
10525    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10526            String stackTrace) {
10527        long now = SystemClock.uptimeMillis();
10528
10529        Long crashTime;
10530        if (!app.isolated) {
10531            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10532        } else {
10533            crashTime = null;
10534        }
10535        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10536            // This process loses!
10537            Slog.w(TAG, "Process " + app.info.processName
10538                    + " has crashed too many times: killing!");
10539            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10540                    app.userId, app.info.processName, app.uid);
10541            mStackSupervisor.handleAppCrashLocked(app);
10542            if (!app.persistent) {
10543                // We don't want to start this process again until the user
10544                // explicitly does so...  but for persistent process, we really
10545                // need to keep it running.  If a persistent process is actually
10546                // repeatedly crashing, then badness for everyone.
10547                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10548                        app.info.processName);
10549                if (!app.isolated) {
10550                    // XXX We don't have a way to mark isolated processes
10551                    // as bad, since they don't have a peristent identity.
10552                    mBadProcesses.put(app.info.processName, app.uid,
10553                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10554                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10555                }
10556                app.bad = true;
10557                app.removed = true;
10558                // Don't let services in this process be restarted and potentially
10559                // annoy the user repeatedly.  Unless it is persistent, since those
10560                // processes run critical code.
10561                removeProcessLocked(app, false, false, "crash");
10562                mStackSupervisor.resumeTopActivitiesLocked();
10563                return false;
10564            }
10565            mStackSupervisor.resumeTopActivitiesLocked();
10566        } else {
10567            mStackSupervisor.finishTopRunningActivityLocked(app);
10568        }
10569
10570        // Bump up the crash count of any services currently running in the proc.
10571        for (int i=app.services.size()-1; i>=0; i--) {
10572            // Any services running in the application need to be placed
10573            // back in the pending list.
10574            ServiceRecord sr = app.services.valueAt(i);
10575            sr.crashCount++;
10576        }
10577
10578        // If the crashing process is what we consider to be the "home process" and it has been
10579        // replaced by a third-party app, clear the package preferred activities from packages
10580        // with a home activity running in the process to prevent a repeatedly crashing app
10581        // from blocking the user to manually clear the list.
10582        final ArrayList<ActivityRecord> activities = app.activities;
10583        if (app == mHomeProcess && activities.size() > 0
10584                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10585            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10586                final ActivityRecord r = activities.get(activityNdx);
10587                if (r.isHomeActivity()) {
10588                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10589                    try {
10590                        ActivityThread.getPackageManager()
10591                                .clearPackagePreferredActivities(r.packageName);
10592                    } catch (RemoteException c) {
10593                        // pm is in same process, this will never happen.
10594                    }
10595                }
10596            }
10597        }
10598
10599        if (!app.isolated) {
10600            // XXX Can't keep track of crash times for isolated processes,
10601            // because they don't have a perisistent identity.
10602            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10603        }
10604
10605        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10606        return true;
10607    }
10608
10609    void startAppProblemLocked(ProcessRecord app) {
10610        // If this app is not running under the current user, then we
10611        // can't give it a report button because that would require
10612        // launching the report UI under a different user.
10613        app.errorReportReceiver = null;
10614
10615        for (int userId : mCurrentProfileIds) {
10616            if (app.userId == userId) {
10617                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10618                        mContext, app.info.packageName, app.info.flags);
10619            }
10620        }
10621        skipCurrentReceiverLocked(app);
10622    }
10623
10624    void skipCurrentReceiverLocked(ProcessRecord app) {
10625        for (BroadcastQueue queue : mBroadcastQueues) {
10626            queue.skipCurrentReceiverLocked(app);
10627        }
10628    }
10629
10630    /**
10631     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10632     * The application process will exit immediately after this call returns.
10633     * @param app object of the crashing app, null for the system server
10634     * @param crashInfo describing the exception
10635     */
10636    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10637        ProcessRecord r = findAppProcess(app, "Crash");
10638        final String processName = app == null ? "system_server"
10639                : (r == null ? "unknown" : r.processName);
10640
10641        handleApplicationCrashInner("crash", r, processName, crashInfo);
10642    }
10643
10644    /* Native crash reporting uses this inner version because it needs to be somewhat
10645     * decoupled from the AM-managed cleanup lifecycle
10646     */
10647    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10648            ApplicationErrorReport.CrashInfo crashInfo) {
10649        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10650                UserHandle.getUserId(Binder.getCallingUid()), processName,
10651                r == null ? -1 : r.info.flags,
10652                crashInfo.exceptionClassName,
10653                crashInfo.exceptionMessage,
10654                crashInfo.throwFileName,
10655                crashInfo.throwLineNumber);
10656
10657        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10658
10659        crashApplication(r, crashInfo);
10660    }
10661
10662    public void handleApplicationStrictModeViolation(
10663            IBinder app,
10664            int violationMask,
10665            StrictMode.ViolationInfo info) {
10666        ProcessRecord r = findAppProcess(app, "StrictMode");
10667        if (r == null) {
10668            return;
10669        }
10670
10671        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10672            Integer stackFingerprint = info.hashCode();
10673            boolean logIt = true;
10674            synchronized (mAlreadyLoggedViolatedStacks) {
10675                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10676                    logIt = false;
10677                    // TODO: sub-sample into EventLog for these, with
10678                    // the info.durationMillis?  Then we'd get
10679                    // the relative pain numbers, without logging all
10680                    // the stack traces repeatedly.  We'd want to do
10681                    // likewise in the client code, which also does
10682                    // dup suppression, before the Binder call.
10683                } else {
10684                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10685                        mAlreadyLoggedViolatedStacks.clear();
10686                    }
10687                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10688                }
10689            }
10690            if (logIt) {
10691                logStrictModeViolationToDropBox(r, info);
10692            }
10693        }
10694
10695        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10696            AppErrorResult result = new AppErrorResult();
10697            synchronized (this) {
10698                final long origId = Binder.clearCallingIdentity();
10699
10700                Message msg = Message.obtain();
10701                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10702                HashMap<String, Object> data = new HashMap<String, Object>();
10703                data.put("result", result);
10704                data.put("app", r);
10705                data.put("violationMask", violationMask);
10706                data.put("info", info);
10707                msg.obj = data;
10708                mHandler.sendMessage(msg);
10709
10710                Binder.restoreCallingIdentity(origId);
10711            }
10712            int res = result.get();
10713            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10714        }
10715    }
10716
10717    // Depending on the policy in effect, there could be a bunch of
10718    // these in quick succession so we try to batch these together to
10719    // minimize disk writes, number of dropbox entries, and maximize
10720    // compression, by having more fewer, larger records.
10721    private void logStrictModeViolationToDropBox(
10722            ProcessRecord process,
10723            StrictMode.ViolationInfo info) {
10724        if (info == null) {
10725            return;
10726        }
10727        final boolean isSystemApp = process == null ||
10728                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10729                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10730        final String processName = process == null ? "unknown" : process.processName;
10731        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10732        final DropBoxManager dbox = (DropBoxManager)
10733                mContext.getSystemService(Context.DROPBOX_SERVICE);
10734
10735        // Exit early if the dropbox isn't configured to accept this report type.
10736        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10737
10738        boolean bufferWasEmpty;
10739        boolean needsFlush;
10740        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10741        synchronized (sb) {
10742            bufferWasEmpty = sb.length() == 0;
10743            appendDropBoxProcessHeaders(process, processName, sb);
10744            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10745            sb.append("System-App: ").append(isSystemApp).append("\n");
10746            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10747            if (info.violationNumThisLoop != 0) {
10748                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10749            }
10750            if (info.numAnimationsRunning != 0) {
10751                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10752            }
10753            if (info.broadcastIntentAction != null) {
10754                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10755            }
10756            if (info.durationMillis != -1) {
10757                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10758            }
10759            if (info.numInstances != -1) {
10760                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10761            }
10762            if (info.tags != null) {
10763                for (String tag : info.tags) {
10764                    sb.append("Span-Tag: ").append(tag).append("\n");
10765                }
10766            }
10767            sb.append("\n");
10768            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10769                sb.append(info.crashInfo.stackTrace);
10770            }
10771            sb.append("\n");
10772
10773            // Only buffer up to ~64k.  Various logging bits truncate
10774            // things at 128k.
10775            needsFlush = (sb.length() > 64 * 1024);
10776        }
10777
10778        // Flush immediately if the buffer's grown too large, or this
10779        // is a non-system app.  Non-system apps are isolated with a
10780        // different tag & policy and not batched.
10781        //
10782        // Batching is useful during internal testing with
10783        // StrictMode settings turned up high.  Without batching,
10784        // thousands of separate files could be created on boot.
10785        if (!isSystemApp || needsFlush) {
10786            new Thread("Error dump: " + dropboxTag) {
10787                @Override
10788                public void run() {
10789                    String report;
10790                    synchronized (sb) {
10791                        report = sb.toString();
10792                        sb.delete(0, sb.length());
10793                        sb.trimToSize();
10794                    }
10795                    if (report.length() != 0) {
10796                        dbox.addText(dropboxTag, report);
10797                    }
10798                }
10799            }.start();
10800            return;
10801        }
10802
10803        // System app batching:
10804        if (!bufferWasEmpty) {
10805            // An existing dropbox-writing thread is outstanding, so
10806            // we don't need to start it up.  The existing thread will
10807            // catch the buffer appends we just did.
10808            return;
10809        }
10810
10811        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10812        // (After this point, we shouldn't access AMS internal data structures.)
10813        new Thread("Error dump: " + dropboxTag) {
10814            @Override
10815            public void run() {
10816                // 5 second sleep to let stacks arrive and be batched together
10817                try {
10818                    Thread.sleep(5000);  // 5 seconds
10819                } catch (InterruptedException e) {}
10820
10821                String errorReport;
10822                synchronized (mStrictModeBuffer) {
10823                    errorReport = mStrictModeBuffer.toString();
10824                    if (errorReport.length() == 0) {
10825                        return;
10826                    }
10827                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10828                    mStrictModeBuffer.trimToSize();
10829                }
10830                dbox.addText(dropboxTag, errorReport);
10831            }
10832        }.start();
10833    }
10834
10835    /**
10836     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10837     * @param app object of the crashing app, null for the system server
10838     * @param tag reported by the caller
10839     * @param crashInfo describing the context of the error
10840     * @return true if the process should exit immediately (WTF is fatal)
10841     */
10842    public boolean handleApplicationWtf(IBinder app, String tag,
10843            ApplicationErrorReport.CrashInfo crashInfo) {
10844        ProcessRecord r = findAppProcess(app, "WTF");
10845        final String processName = app == null ? "system_server"
10846                : (r == null ? "unknown" : r.processName);
10847
10848        EventLog.writeEvent(EventLogTags.AM_WTF,
10849                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10850                processName,
10851                r == null ? -1 : r.info.flags,
10852                tag, crashInfo.exceptionMessage);
10853
10854        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10855
10856        if (r != null && r.pid != Process.myPid() &&
10857                Settings.Global.getInt(mContext.getContentResolver(),
10858                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10859            crashApplication(r, crashInfo);
10860            return true;
10861        } else {
10862            return false;
10863        }
10864    }
10865
10866    /**
10867     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10868     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10869     */
10870    private ProcessRecord findAppProcess(IBinder app, String reason) {
10871        if (app == null) {
10872            return null;
10873        }
10874
10875        synchronized (this) {
10876            final int NP = mProcessNames.getMap().size();
10877            for (int ip=0; ip<NP; ip++) {
10878                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10879                final int NA = apps.size();
10880                for (int ia=0; ia<NA; ia++) {
10881                    ProcessRecord p = apps.valueAt(ia);
10882                    if (p.thread != null && p.thread.asBinder() == app) {
10883                        return p;
10884                    }
10885                }
10886            }
10887
10888            Slog.w(TAG, "Can't find mystery application for " + reason
10889                    + " from pid=" + Binder.getCallingPid()
10890                    + " uid=" + Binder.getCallingUid() + ": " + app);
10891            return null;
10892        }
10893    }
10894
10895    /**
10896     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10897     * to append various headers to the dropbox log text.
10898     */
10899    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10900            StringBuilder sb) {
10901        // Watchdog thread ends up invoking this function (with
10902        // a null ProcessRecord) to add the stack file to dropbox.
10903        // Do not acquire a lock on this (am) in such cases, as it
10904        // could cause a potential deadlock, if and when watchdog
10905        // is invoked due to unavailability of lock on am and it
10906        // would prevent watchdog from killing system_server.
10907        if (process == null) {
10908            sb.append("Process: ").append(processName).append("\n");
10909            return;
10910        }
10911        // Note: ProcessRecord 'process' is guarded by the service
10912        // instance.  (notably process.pkgList, which could otherwise change
10913        // concurrently during execution of this method)
10914        synchronized (this) {
10915            sb.append("Process: ").append(processName).append("\n");
10916            int flags = process.info.flags;
10917            IPackageManager pm = AppGlobals.getPackageManager();
10918            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10919            for (int ip=0; ip<process.pkgList.size(); ip++) {
10920                String pkg = process.pkgList.keyAt(ip);
10921                sb.append("Package: ").append(pkg);
10922                try {
10923                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10924                    if (pi != null) {
10925                        sb.append(" v").append(pi.versionCode);
10926                        if (pi.versionName != null) {
10927                            sb.append(" (").append(pi.versionName).append(")");
10928                        }
10929                    }
10930                } catch (RemoteException e) {
10931                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10932                }
10933                sb.append("\n");
10934            }
10935        }
10936    }
10937
10938    private static String processClass(ProcessRecord process) {
10939        if (process == null || process.pid == MY_PID) {
10940            return "system_server";
10941        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10942            return "system_app";
10943        } else {
10944            return "data_app";
10945        }
10946    }
10947
10948    /**
10949     * Write a description of an error (crash, WTF, ANR) to the drop box.
10950     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10951     * @param process which caused the error, null means the system server
10952     * @param activity which triggered the error, null if unknown
10953     * @param parent activity related to the error, null if unknown
10954     * @param subject line related to the error, null if absent
10955     * @param report in long form describing the error, null if absent
10956     * @param logFile to include in the report, null if none
10957     * @param crashInfo giving an application stack trace, null if absent
10958     */
10959    public void addErrorToDropBox(String eventType,
10960            ProcessRecord process, String processName, ActivityRecord activity,
10961            ActivityRecord parent, String subject,
10962            final String report, final File logFile,
10963            final ApplicationErrorReport.CrashInfo crashInfo) {
10964        // NOTE -- this must never acquire the ActivityManagerService lock,
10965        // otherwise the watchdog may be prevented from resetting the system.
10966
10967        final String dropboxTag = processClass(process) + "_" + eventType;
10968        final DropBoxManager dbox = (DropBoxManager)
10969                mContext.getSystemService(Context.DROPBOX_SERVICE);
10970
10971        // Exit early if the dropbox isn't configured to accept this report type.
10972        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10973
10974        final StringBuilder sb = new StringBuilder(1024);
10975        appendDropBoxProcessHeaders(process, processName, sb);
10976        if (activity != null) {
10977            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10978        }
10979        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10980            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10981        }
10982        if (parent != null && parent != activity) {
10983            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10984        }
10985        if (subject != null) {
10986            sb.append("Subject: ").append(subject).append("\n");
10987        }
10988        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10989        if (Debug.isDebuggerConnected()) {
10990            sb.append("Debugger: Connected\n");
10991        }
10992        sb.append("\n");
10993
10994        // Do the rest in a worker thread to avoid blocking the caller on I/O
10995        // (After this point, we shouldn't access AMS internal data structures.)
10996        Thread worker = new Thread("Error dump: " + dropboxTag) {
10997            @Override
10998            public void run() {
10999                if (report != null) {
11000                    sb.append(report);
11001                }
11002                if (logFile != null) {
11003                    try {
11004                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11005                                    "\n\n[[TRUNCATED]]"));
11006                    } catch (IOException e) {
11007                        Slog.e(TAG, "Error reading " + logFile, e);
11008                    }
11009                }
11010                if (crashInfo != null && crashInfo.stackTrace != null) {
11011                    sb.append(crashInfo.stackTrace);
11012                }
11013
11014                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11015                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11016                if (lines > 0) {
11017                    sb.append("\n");
11018
11019                    // Merge several logcat streams, and take the last N lines
11020                    InputStreamReader input = null;
11021                    try {
11022                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11023                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11024                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11025
11026                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11027                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11028                        input = new InputStreamReader(logcat.getInputStream());
11029
11030                        int num;
11031                        char[] buf = new char[8192];
11032                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11033                    } catch (IOException e) {
11034                        Slog.e(TAG, "Error running logcat", e);
11035                    } finally {
11036                        if (input != null) try { input.close(); } catch (IOException e) {}
11037                    }
11038                }
11039
11040                dbox.addText(dropboxTag, sb.toString());
11041            }
11042        };
11043
11044        if (process == null) {
11045            // If process is null, we are being called from some internal code
11046            // and may be about to die -- run this synchronously.
11047            worker.run();
11048        } else {
11049            worker.start();
11050        }
11051    }
11052
11053    /**
11054     * Bring up the "unexpected error" dialog box for a crashing app.
11055     * Deal with edge cases (intercepts from instrumented applications,
11056     * ActivityController, error intent receivers, that sort of thing).
11057     * @param r the application crashing
11058     * @param crashInfo describing the failure
11059     */
11060    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11061        long timeMillis = System.currentTimeMillis();
11062        String shortMsg = crashInfo.exceptionClassName;
11063        String longMsg = crashInfo.exceptionMessage;
11064        String stackTrace = crashInfo.stackTrace;
11065        if (shortMsg != null && longMsg != null) {
11066            longMsg = shortMsg + ": " + longMsg;
11067        } else if (shortMsg != null) {
11068            longMsg = shortMsg;
11069        }
11070
11071        AppErrorResult result = new AppErrorResult();
11072        synchronized (this) {
11073            if (mController != null) {
11074                try {
11075                    String name = r != null ? r.processName : null;
11076                    int pid = r != null ? r.pid : Binder.getCallingPid();
11077                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11078                    if (!mController.appCrashed(name, pid,
11079                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11080                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11081                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11082                            Slog.w(TAG, "Skip killing native crashed app " + name
11083                                    + "(" + pid + ") during testing");
11084                        } else {
11085                            Slog.w(TAG, "Force-killing crashed app " + name
11086                                    + " at watcher's request");
11087                            Process.killProcess(pid);
11088                            if (r != null) {
11089                                Process.killProcessGroup(uid, pid);
11090                            }
11091                        }
11092                        return;
11093                    }
11094                } catch (RemoteException e) {
11095                    mController = null;
11096                    Watchdog.getInstance().setActivityController(null);
11097                }
11098            }
11099
11100            final long origId = Binder.clearCallingIdentity();
11101
11102            // If this process is running instrumentation, finish it.
11103            if (r != null && r.instrumentationClass != null) {
11104                Slog.w(TAG, "Error in app " + r.processName
11105                      + " running instrumentation " + r.instrumentationClass + ":");
11106                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11107                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11108                Bundle info = new Bundle();
11109                info.putString("shortMsg", shortMsg);
11110                info.putString("longMsg", longMsg);
11111                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11112                Binder.restoreCallingIdentity(origId);
11113                return;
11114            }
11115
11116            // If we can't identify the process or it's already exceeded its crash quota,
11117            // quit right away without showing a crash dialog.
11118            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11119                Binder.restoreCallingIdentity(origId);
11120                return;
11121            }
11122
11123            Message msg = Message.obtain();
11124            msg.what = SHOW_ERROR_MSG;
11125            HashMap data = new HashMap();
11126            data.put("result", result);
11127            data.put("app", r);
11128            msg.obj = data;
11129            mHandler.sendMessage(msg);
11130
11131            Binder.restoreCallingIdentity(origId);
11132        }
11133
11134        int res = result.get();
11135
11136        Intent appErrorIntent = null;
11137        synchronized (this) {
11138            if (r != null && !r.isolated) {
11139                // XXX Can't keep track of crash time for isolated processes,
11140                // since they don't have a persistent identity.
11141                mProcessCrashTimes.put(r.info.processName, r.uid,
11142                        SystemClock.uptimeMillis());
11143            }
11144            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11145                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11146            }
11147        }
11148
11149        if (appErrorIntent != null) {
11150            try {
11151                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11152            } catch (ActivityNotFoundException e) {
11153                Slog.w(TAG, "bug report receiver dissappeared", e);
11154            }
11155        }
11156    }
11157
11158    Intent createAppErrorIntentLocked(ProcessRecord r,
11159            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11160        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11161        if (report == null) {
11162            return null;
11163        }
11164        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11165        result.setComponent(r.errorReportReceiver);
11166        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11167        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11168        return result;
11169    }
11170
11171    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11172            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11173        if (r.errorReportReceiver == null) {
11174            return null;
11175        }
11176
11177        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11178            return null;
11179        }
11180
11181        ApplicationErrorReport report = new ApplicationErrorReport();
11182        report.packageName = r.info.packageName;
11183        report.installerPackageName = r.errorReportReceiver.getPackageName();
11184        report.processName = r.processName;
11185        report.time = timeMillis;
11186        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11187
11188        if (r.crashing || r.forceCrashReport) {
11189            report.type = ApplicationErrorReport.TYPE_CRASH;
11190            report.crashInfo = crashInfo;
11191        } else if (r.notResponding) {
11192            report.type = ApplicationErrorReport.TYPE_ANR;
11193            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11194
11195            report.anrInfo.activity = r.notRespondingReport.tag;
11196            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11197            report.anrInfo.info = r.notRespondingReport.longMsg;
11198        }
11199
11200        return report;
11201    }
11202
11203    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11204        enforceNotIsolatedCaller("getProcessesInErrorState");
11205        // assume our apps are happy - lazy create the list
11206        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11207
11208        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11209                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11210        int userId = UserHandle.getUserId(Binder.getCallingUid());
11211
11212        synchronized (this) {
11213
11214            // iterate across all processes
11215            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11216                ProcessRecord app = mLruProcesses.get(i);
11217                if (!allUsers && app.userId != userId) {
11218                    continue;
11219                }
11220                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11221                    // This one's in trouble, so we'll generate a report for it
11222                    // crashes are higher priority (in case there's a crash *and* an anr)
11223                    ActivityManager.ProcessErrorStateInfo report = null;
11224                    if (app.crashing) {
11225                        report = app.crashingReport;
11226                    } else if (app.notResponding) {
11227                        report = app.notRespondingReport;
11228                    }
11229
11230                    if (report != null) {
11231                        if (errList == null) {
11232                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11233                        }
11234                        errList.add(report);
11235                    } else {
11236                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11237                                " crashing = " + app.crashing +
11238                                " notResponding = " + app.notResponding);
11239                    }
11240                }
11241            }
11242        }
11243
11244        return errList;
11245    }
11246
11247    static int procStateToImportance(int procState, int memAdj,
11248            ActivityManager.RunningAppProcessInfo currApp) {
11249        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11250        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11251            currApp.lru = memAdj;
11252        } else {
11253            currApp.lru = 0;
11254        }
11255        return imp;
11256    }
11257
11258    private void fillInProcMemInfo(ProcessRecord app,
11259            ActivityManager.RunningAppProcessInfo outInfo) {
11260        outInfo.pid = app.pid;
11261        outInfo.uid = app.info.uid;
11262        if (mHeavyWeightProcess == app) {
11263            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11264        }
11265        if (app.persistent) {
11266            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11267        }
11268        if (app.activities.size() > 0) {
11269            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11270        }
11271        outInfo.lastTrimLevel = app.trimMemoryLevel;
11272        int adj = app.curAdj;
11273        int procState = app.curProcState;
11274        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11275        outInfo.importanceReasonCode = app.adjTypeCode;
11276        outInfo.processState = app.curProcState;
11277    }
11278
11279    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11280        enforceNotIsolatedCaller("getRunningAppProcesses");
11281        // Lazy instantiation of list
11282        List<ActivityManager.RunningAppProcessInfo> runList = null;
11283        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11284                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11285        int userId = UserHandle.getUserId(Binder.getCallingUid());
11286        synchronized (this) {
11287            // Iterate across all processes
11288            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11289                ProcessRecord app = mLruProcesses.get(i);
11290                if (!allUsers && app.userId != userId) {
11291                    continue;
11292                }
11293                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11294                    // Generate process state info for running application
11295                    ActivityManager.RunningAppProcessInfo currApp =
11296                        new ActivityManager.RunningAppProcessInfo(app.processName,
11297                                app.pid, app.getPackageList());
11298                    fillInProcMemInfo(app, currApp);
11299                    if (app.adjSource instanceof ProcessRecord) {
11300                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11301                        currApp.importanceReasonImportance =
11302                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11303                                        app.adjSourceProcState);
11304                    } else if (app.adjSource instanceof ActivityRecord) {
11305                        ActivityRecord r = (ActivityRecord)app.adjSource;
11306                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11307                    }
11308                    if (app.adjTarget instanceof ComponentName) {
11309                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11310                    }
11311                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11312                    //        + " lru=" + currApp.lru);
11313                    if (runList == null) {
11314                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11315                    }
11316                    runList.add(currApp);
11317                }
11318            }
11319        }
11320        return runList;
11321    }
11322
11323    public List<ApplicationInfo> getRunningExternalApplications() {
11324        enforceNotIsolatedCaller("getRunningExternalApplications");
11325        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11326        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11327        if (runningApps != null && runningApps.size() > 0) {
11328            Set<String> extList = new HashSet<String>();
11329            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11330                if (app.pkgList != null) {
11331                    for (String pkg : app.pkgList) {
11332                        extList.add(pkg);
11333                    }
11334                }
11335            }
11336            IPackageManager pm = AppGlobals.getPackageManager();
11337            for (String pkg : extList) {
11338                try {
11339                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11340                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11341                        retList.add(info);
11342                    }
11343                } catch (RemoteException e) {
11344                }
11345            }
11346        }
11347        return retList;
11348    }
11349
11350    @Override
11351    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11352        enforceNotIsolatedCaller("getMyMemoryState");
11353        synchronized (this) {
11354            ProcessRecord proc;
11355            synchronized (mPidsSelfLocked) {
11356                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11357            }
11358            fillInProcMemInfo(proc, outInfo);
11359        }
11360    }
11361
11362    @Override
11363    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11364        if (checkCallingPermission(android.Manifest.permission.DUMP)
11365                != PackageManager.PERMISSION_GRANTED) {
11366            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11367                    + Binder.getCallingPid()
11368                    + ", uid=" + Binder.getCallingUid()
11369                    + " without permission "
11370                    + android.Manifest.permission.DUMP);
11371            return;
11372        }
11373
11374        boolean dumpAll = false;
11375        boolean dumpClient = false;
11376        String dumpPackage = null;
11377
11378        int opti = 0;
11379        while (opti < args.length) {
11380            String opt = args[opti];
11381            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11382                break;
11383            }
11384            opti++;
11385            if ("-a".equals(opt)) {
11386                dumpAll = true;
11387            } else if ("-c".equals(opt)) {
11388                dumpClient = true;
11389            } else if ("-h".equals(opt)) {
11390                pw.println("Activity manager dump options:");
11391                pw.println("  [-a] [-c] [-h] [cmd] ...");
11392                pw.println("  cmd may be one of:");
11393                pw.println("    a[ctivities]: activity stack state");
11394                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11395                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11396                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11397                pw.println("    o[om]: out of memory management");
11398                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11399                pw.println("    provider [COMP_SPEC]: provider client-side state");
11400                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11401                pw.println("    service [COMP_SPEC]: service client-side state");
11402                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11403                pw.println("    all: dump all activities");
11404                pw.println("    top: dump the top activity");
11405                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11406                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11407                pw.println("    a partial substring in a component name, a");
11408                pw.println("    hex object identifier.");
11409                pw.println("  -a: include all available server state.");
11410                pw.println("  -c: include client state.");
11411                return;
11412            } else {
11413                pw.println("Unknown argument: " + opt + "; use -h for help");
11414            }
11415        }
11416
11417        long origId = Binder.clearCallingIdentity();
11418        boolean more = false;
11419        // Is the caller requesting to dump a particular piece of data?
11420        if (opti < args.length) {
11421            String cmd = args[opti];
11422            opti++;
11423            if ("activities".equals(cmd) || "a".equals(cmd)) {
11424                synchronized (this) {
11425                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11426                }
11427            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11428                String[] newArgs;
11429                String name;
11430                if (opti >= args.length) {
11431                    name = null;
11432                    newArgs = EMPTY_STRING_ARRAY;
11433                } else {
11434                    name = args[opti];
11435                    opti++;
11436                    newArgs = new String[args.length - opti];
11437                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11438                            args.length - opti);
11439                }
11440                synchronized (this) {
11441                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11442                }
11443            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11444                String[] newArgs;
11445                String name;
11446                if (opti >= args.length) {
11447                    name = null;
11448                    newArgs = EMPTY_STRING_ARRAY;
11449                } else {
11450                    name = args[opti];
11451                    opti++;
11452                    newArgs = new String[args.length - opti];
11453                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11454                            args.length - opti);
11455                }
11456                synchronized (this) {
11457                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11458                }
11459            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11460                String[] newArgs;
11461                String name;
11462                if (opti >= args.length) {
11463                    name = null;
11464                    newArgs = EMPTY_STRING_ARRAY;
11465                } else {
11466                    name = args[opti];
11467                    opti++;
11468                    newArgs = new String[args.length - opti];
11469                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11470                            args.length - opti);
11471                }
11472                synchronized (this) {
11473                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11474                }
11475            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11476                synchronized (this) {
11477                    dumpOomLocked(fd, pw, args, opti, true);
11478                }
11479            } else if ("provider".equals(cmd)) {
11480                String[] newArgs;
11481                String name;
11482                if (opti >= args.length) {
11483                    name = null;
11484                    newArgs = EMPTY_STRING_ARRAY;
11485                } else {
11486                    name = args[opti];
11487                    opti++;
11488                    newArgs = new String[args.length - opti];
11489                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11490                }
11491                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11492                    pw.println("No providers match: " + name);
11493                    pw.println("Use -h for help.");
11494                }
11495            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11496                synchronized (this) {
11497                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11498                }
11499            } else if ("service".equals(cmd)) {
11500                String[] newArgs;
11501                String name;
11502                if (opti >= args.length) {
11503                    name = null;
11504                    newArgs = EMPTY_STRING_ARRAY;
11505                } else {
11506                    name = args[opti];
11507                    opti++;
11508                    newArgs = new String[args.length - opti];
11509                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11510                            args.length - opti);
11511                }
11512                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11513                    pw.println("No services match: " + name);
11514                    pw.println("Use -h for help.");
11515                }
11516            } else if ("package".equals(cmd)) {
11517                String[] newArgs;
11518                if (opti >= args.length) {
11519                    pw.println("package: no package name specified");
11520                    pw.println("Use -h for help.");
11521                } else {
11522                    dumpPackage = args[opti];
11523                    opti++;
11524                    newArgs = new String[args.length - opti];
11525                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11526                            args.length - opti);
11527                    args = newArgs;
11528                    opti = 0;
11529                    more = true;
11530                }
11531            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11532                synchronized (this) {
11533                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11534                }
11535            } else {
11536                // Dumping a single activity?
11537                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11538                    pw.println("Bad activity command, or no activities match: " + cmd);
11539                    pw.println("Use -h for help.");
11540                }
11541            }
11542            if (!more) {
11543                Binder.restoreCallingIdentity(origId);
11544                return;
11545            }
11546        }
11547
11548        // No piece of data specified, dump everything.
11549        synchronized (this) {
11550            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11551            pw.println();
11552            if (dumpAll) {
11553                pw.println("-------------------------------------------------------------------------------");
11554            }
11555            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11556            pw.println();
11557            if (dumpAll) {
11558                pw.println("-------------------------------------------------------------------------------");
11559            }
11560            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11561            pw.println();
11562            if (dumpAll) {
11563                pw.println("-------------------------------------------------------------------------------");
11564            }
11565            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11566            pw.println();
11567            if (dumpAll) {
11568                pw.println("-------------------------------------------------------------------------------");
11569            }
11570            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11571            pw.println();
11572            if (dumpAll) {
11573                pw.println("-------------------------------------------------------------------------------");
11574            }
11575            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11576        }
11577        Binder.restoreCallingIdentity(origId);
11578    }
11579
11580    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11581            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11582        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11583
11584        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11585                dumpPackage);
11586        boolean needSep = printedAnything;
11587
11588        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11589                dumpPackage, needSep, "  mFocusedActivity: ");
11590        if (printed) {
11591            printedAnything = true;
11592            needSep = false;
11593        }
11594
11595        if (dumpPackage == null) {
11596            if (needSep) {
11597                pw.println();
11598            }
11599            needSep = true;
11600            printedAnything = true;
11601            mStackSupervisor.dump(pw, "  ");
11602        }
11603
11604        if (mRecentTasks.size() > 0) {
11605            boolean printedHeader = false;
11606
11607            final int N = mRecentTasks.size();
11608            for (int i=0; i<N; i++) {
11609                TaskRecord tr = mRecentTasks.get(i);
11610                if (dumpPackage != null) {
11611                    if (tr.realActivity == null ||
11612                            !dumpPackage.equals(tr.realActivity)) {
11613                        continue;
11614                    }
11615                }
11616                if (!printedHeader) {
11617                    if (needSep) {
11618                        pw.println();
11619                    }
11620                    pw.println("  Recent tasks:");
11621                    printedHeader = true;
11622                    printedAnything = true;
11623                }
11624                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11625                        pw.println(tr);
11626                if (dumpAll) {
11627                    mRecentTasks.get(i).dump(pw, "    ");
11628                }
11629            }
11630        }
11631
11632        if (!printedAnything) {
11633            pw.println("  (nothing)");
11634        }
11635    }
11636
11637    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11638            int opti, boolean dumpAll, String dumpPackage) {
11639        boolean needSep = false;
11640        boolean printedAnything = false;
11641        int numPers = 0;
11642
11643        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11644
11645        if (dumpAll) {
11646            final int NP = mProcessNames.getMap().size();
11647            for (int ip=0; ip<NP; ip++) {
11648                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11649                final int NA = procs.size();
11650                for (int ia=0; ia<NA; ia++) {
11651                    ProcessRecord r = procs.valueAt(ia);
11652                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11653                        continue;
11654                    }
11655                    if (!needSep) {
11656                        pw.println("  All known processes:");
11657                        needSep = true;
11658                        printedAnything = true;
11659                    }
11660                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11661                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11662                        pw.print(" "); pw.println(r);
11663                    r.dump(pw, "    ");
11664                    if (r.persistent) {
11665                        numPers++;
11666                    }
11667                }
11668            }
11669        }
11670
11671        if (mIsolatedProcesses.size() > 0) {
11672            boolean printed = false;
11673            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11674                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11675                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11676                    continue;
11677                }
11678                if (!printed) {
11679                    if (needSep) {
11680                        pw.println();
11681                    }
11682                    pw.println("  Isolated process list (sorted by uid):");
11683                    printedAnything = true;
11684                    printed = true;
11685                    needSep = true;
11686                }
11687                pw.println(String.format("%sIsolated #%2d: %s",
11688                        "    ", i, r.toString()));
11689            }
11690        }
11691
11692        if (mLruProcesses.size() > 0) {
11693            if (needSep) {
11694                pw.println();
11695            }
11696            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11697                    pw.print(" total, non-act at ");
11698                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11699                    pw.print(", non-svc at ");
11700                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11701                    pw.println("):");
11702            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11703            needSep = true;
11704            printedAnything = true;
11705        }
11706
11707        if (dumpAll || dumpPackage != null) {
11708            synchronized (mPidsSelfLocked) {
11709                boolean printed = false;
11710                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11711                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11712                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11713                        continue;
11714                    }
11715                    if (!printed) {
11716                        if (needSep) pw.println();
11717                        needSep = true;
11718                        pw.println("  PID mappings:");
11719                        printed = true;
11720                        printedAnything = true;
11721                    }
11722                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11723                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11724                }
11725            }
11726        }
11727
11728        if (mForegroundProcesses.size() > 0) {
11729            synchronized (mPidsSelfLocked) {
11730                boolean printed = false;
11731                for (int i=0; i<mForegroundProcesses.size(); i++) {
11732                    ProcessRecord r = mPidsSelfLocked.get(
11733                            mForegroundProcesses.valueAt(i).pid);
11734                    if (dumpPackage != null && (r == null
11735                            || !r.pkgList.containsKey(dumpPackage))) {
11736                        continue;
11737                    }
11738                    if (!printed) {
11739                        if (needSep) pw.println();
11740                        needSep = true;
11741                        pw.println("  Foreground Processes:");
11742                        printed = true;
11743                        printedAnything = true;
11744                    }
11745                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11746                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11747                }
11748            }
11749        }
11750
11751        if (mPersistentStartingProcesses.size() > 0) {
11752            if (needSep) pw.println();
11753            needSep = true;
11754            printedAnything = true;
11755            pw.println("  Persisent processes that are starting:");
11756            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11757                    "Starting Norm", "Restarting PERS", dumpPackage);
11758        }
11759
11760        if (mRemovedProcesses.size() > 0) {
11761            if (needSep) pw.println();
11762            needSep = true;
11763            printedAnything = true;
11764            pw.println("  Processes that are being removed:");
11765            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11766                    "Removed Norm", "Removed PERS", dumpPackage);
11767        }
11768
11769        if (mProcessesOnHold.size() > 0) {
11770            if (needSep) pw.println();
11771            needSep = true;
11772            printedAnything = true;
11773            pw.println("  Processes that are on old until the system is ready:");
11774            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11775                    "OnHold Norm", "OnHold PERS", dumpPackage);
11776        }
11777
11778        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11779
11780        if (mProcessCrashTimes.getMap().size() > 0) {
11781            boolean printed = false;
11782            long now = SystemClock.uptimeMillis();
11783            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11784            final int NP = pmap.size();
11785            for (int ip=0; ip<NP; ip++) {
11786                String pname = pmap.keyAt(ip);
11787                SparseArray<Long> uids = pmap.valueAt(ip);
11788                final int N = uids.size();
11789                for (int i=0; i<N; i++) {
11790                    int puid = uids.keyAt(i);
11791                    ProcessRecord r = mProcessNames.get(pname, puid);
11792                    if (dumpPackage != null && (r == null
11793                            || !r.pkgList.containsKey(dumpPackage))) {
11794                        continue;
11795                    }
11796                    if (!printed) {
11797                        if (needSep) pw.println();
11798                        needSep = true;
11799                        pw.println("  Time since processes crashed:");
11800                        printed = true;
11801                        printedAnything = true;
11802                    }
11803                    pw.print("    Process "); pw.print(pname);
11804                            pw.print(" uid "); pw.print(puid);
11805                            pw.print(": last crashed ");
11806                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11807                            pw.println(" ago");
11808                }
11809            }
11810        }
11811
11812        if (mBadProcesses.getMap().size() > 0) {
11813            boolean printed = false;
11814            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11815            final int NP = pmap.size();
11816            for (int ip=0; ip<NP; ip++) {
11817                String pname = pmap.keyAt(ip);
11818                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11819                final int N = uids.size();
11820                for (int i=0; i<N; i++) {
11821                    int puid = uids.keyAt(i);
11822                    ProcessRecord r = mProcessNames.get(pname, puid);
11823                    if (dumpPackage != null && (r == null
11824                            || !r.pkgList.containsKey(dumpPackage))) {
11825                        continue;
11826                    }
11827                    if (!printed) {
11828                        if (needSep) pw.println();
11829                        needSep = true;
11830                        pw.println("  Bad processes:");
11831                        printedAnything = true;
11832                    }
11833                    BadProcessInfo info = uids.valueAt(i);
11834                    pw.print("    Bad process "); pw.print(pname);
11835                            pw.print(" uid "); pw.print(puid);
11836                            pw.print(": crashed at time "); pw.println(info.time);
11837                    if (info.shortMsg != null) {
11838                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11839                    }
11840                    if (info.longMsg != null) {
11841                        pw.print("      Long msg: "); pw.println(info.longMsg);
11842                    }
11843                    if (info.stack != null) {
11844                        pw.println("      Stack:");
11845                        int lastPos = 0;
11846                        for (int pos=0; pos<info.stack.length(); pos++) {
11847                            if (info.stack.charAt(pos) == '\n') {
11848                                pw.print("        ");
11849                                pw.write(info.stack, lastPos, pos-lastPos);
11850                                pw.println();
11851                                lastPos = pos+1;
11852                            }
11853                        }
11854                        if (lastPos < info.stack.length()) {
11855                            pw.print("        ");
11856                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11857                            pw.println();
11858                        }
11859                    }
11860                }
11861            }
11862        }
11863
11864        if (dumpPackage == null) {
11865            pw.println();
11866            needSep = false;
11867            pw.println("  mStartedUsers:");
11868            for (int i=0; i<mStartedUsers.size(); i++) {
11869                UserStartedState uss = mStartedUsers.valueAt(i);
11870                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11871                        pw.print(": "); uss.dump("", pw);
11872            }
11873            pw.print("  mStartedUserArray: [");
11874            for (int i=0; i<mStartedUserArray.length; i++) {
11875                if (i > 0) pw.print(", ");
11876                pw.print(mStartedUserArray[i]);
11877            }
11878            pw.println("]");
11879            pw.print("  mUserLru: [");
11880            for (int i=0; i<mUserLru.size(); i++) {
11881                if (i > 0) pw.print(", ");
11882                pw.print(mUserLru.get(i));
11883            }
11884            pw.println("]");
11885            if (dumpAll) {
11886                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11887            }
11888            synchronized (mUserProfileGroupIdsSelfLocked) {
11889                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11890                    pw.println("  mUserProfileGroupIds:");
11891                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11892                        pw.print("    User #");
11893                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11894                        pw.print(" -> profile #");
11895                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11896                    }
11897                }
11898            }
11899        }
11900        if (mHomeProcess != null && (dumpPackage == null
11901                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11902            if (needSep) {
11903                pw.println();
11904                needSep = false;
11905            }
11906            pw.println("  mHomeProcess: " + mHomeProcess);
11907        }
11908        if (mPreviousProcess != null && (dumpPackage == null
11909                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11910            if (needSep) {
11911                pw.println();
11912                needSep = false;
11913            }
11914            pw.println("  mPreviousProcess: " + mPreviousProcess);
11915        }
11916        if (dumpAll) {
11917            StringBuilder sb = new StringBuilder(128);
11918            sb.append("  mPreviousProcessVisibleTime: ");
11919            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11920            pw.println(sb);
11921        }
11922        if (mHeavyWeightProcess != null && (dumpPackage == null
11923                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11924            if (needSep) {
11925                pw.println();
11926                needSep = false;
11927            }
11928            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11929        }
11930        if (dumpPackage == null) {
11931            pw.println("  mConfiguration: " + mConfiguration);
11932        }
11933        if (dumpAll) {
11934            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11935            if (mCompatModePackages.getPackages().size() > 0) {
11936                boolean printed = false;
11937                for (Map.Entry<String, Integer> entry
11938                        : mCompatModePackages.getPackages().entrySet()) {
11939                    String pkg = entry.getKey();
11940                    int mode = entry.getValue();
11941                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11942                        continue;
11943                    }
11944                    if (!printed) {
11945                        pw.println("  mScreenCompatPackages:");
11946                        printed = true;
11947                    }
11948                    pw.print("    "); pw.print(pkg); pw.print(": ");
11949                            pw.print(mode); pw.println();
11950                }
11951            }
11952        }
11953        if (dumpPackage == null) {
11954            if (mSleeping || mWentToSleep || mLockScreenShown) {
11955                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11956                        + " mLockScreenShown " + mLockScreenShown);
11957            }
11958            if (mShuttingDown || mRunningVoice) {
11959                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11960            }
11961        }
11962        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11963                || mOrigWaitForDebugger) {
11964            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11965                    || dumpPackage.equals(mOrigDebugApp)) {
11966                if (needSep) {
11967                    pw.println();
11968                    needSep = false;
11969                }
11970                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11971                        + " mDebugTransient=" + mDebugTransient
11972                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11973            }
11974        }
11975        if (mOpenGlTraceApp != null) {
11976            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11977                if (needSep) {
11978                    pw.println();
11979                    needSep = false;
11980                }
11981                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11982            }
11983        }
11984        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11985                || mProfileFd != null) {
11986            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11987                if (needSep) {
11988                    pw.println();
11989                    needSep = false;
11990                }
11991                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11992                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11993                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11994                        + mAutoStopProfiler);
11995            }
11996        }
11997        if (dumpPackage == null) {
11998            if (mAlwaysFinishActivities || mController != null) {
11999                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12000                        + " mController=" + mController);
12001            }
12002            if (dumpAll) {
12003                pw.println("  Total persistent processes: " + numPers);
12004                pw.println("  mProcessesReady=" + mProcessesReady
12005                        + " mSystemReady=" + mSystemReady);
12006                pw.println("  mBooting=" + mBooting
12007                        + " mBooted=" + mBooted
12008                        + " mFactoryTest=" + mFactoryTest);
12009                pw.print("  mLastPowerCheckRealtime=");
12010                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12011                        pw.println("");
12012                pw.print("  mLastPowerCheckUptime=");
12013                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12014                        pw.println("");
12015                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12016                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12017                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12018                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12019                        + " (" + mLruProcesses.size() + " total)"
12020                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12021                        + " mNumServiceProcs=" + mNumServiceProcs
12022                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12023                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12024                        + " mLastMemoryLevel" + mLastMemoryLevel
12025                        + " mLastNumProcesses" + mLastNumProcesses);
12026                long now = SystemClock.uptimeMillis();
12027                pw.print("  mLastIdleTime=");
12028                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12029                        pw.print(" mLowRamSinceLastIdle=");
12030                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12031                        pw.println();
12032            }
12033        }
12034
12035        if (!printedAnything) {
12036            pw.println("  (nothing)");
12037        }
12038    }
12039
12040    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12041            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12042        if (mProcessesToGc.size() > 0) {
12043            boolean printed = false;
12044            long now = SystemClock.uptimeMillis();
12045            for (int i=0; i<mProcessesToGc.size(); i++) {
12046                ProcessRecord proc = mProcessesToGc.get(i);
12047                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12048                    continue;
12049                }
12050                if (!printed) {
12051                    if (needSep) pw.println();
12052                    needSep = true;
12053                    pw.println("  Processes that are waiting to GC:");
12054                    printed = true;
12055                }
12056                pw.print("    Process "); pw.println(proc);
12057                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12058                        pw.print(", last gced=");
12059                        pw.print(now-proc.lastRequestedGc);
12060                        pw.print(" ms ago, last lowMem=");
12061                        pw.print(now-proc.lastLowMemory);
12062                        pw.println(" ms ago");
12063
12064            }
12065        }
12066        return needSep;
12067    }
12068
12069    void printOomLevel(PrintWriter pw, String name, int adj) {
12070        pw.print("    ");
12071        if (adj >= 0) {
12072            pw.print(' ');
12073            if (adj < 10) pw.print(' ');
12074        } else {
12075            if (adj > -10) pw.print(' ');
12076        }
12077        pw.print(adj);
12078        pw.print(": ");
12079        pw.print(name);
12080        pw.print(" (");
12081        pw.print(mProcessList.getMemLevel(adj)/1024);
12082        pw.println(" kB)");
12083    }
12084
12085    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12086            int opti, boolean dumpAll) {
12087        boolean needSep = false;
12088
12089        if (mLruProcesses.size() > 0) {
12090            if (needSep) pw.println();
12091            needSep = true;
12092            pw.println("  OOM levels:");
12093            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12094            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12095            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12096            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12097            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12098            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12099            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12100            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12101            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12102            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12103            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12104            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12105            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12106
12107            if (needSep) pw.println();
12108            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12109                    pw.print(" total, non-act at ");
12110                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12111                    pw.print(", non-svc at ");
12112                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12113                    pw.println("):");
12114            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12115            needSep = true;
12116        }
12117
12118        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12119
12120        pw.println();
12121        pw.println("  mHomeProcess: " + mHomeProcess);
12122        pw.println("  mPreviousProcess: " + mPreviousProcess);
12123        if (mHeavyWeightProcess != null) {
12124            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12125        }
12126
12127        return true;
12128    }
12129
12130    /**
12131     * There are three ways to call this:
12132     *  - no provider specified: dump all the providers
12133     *  - a flattened component name that matched an existing provider was specified as the
12134     *    first arg: dump that one provider
12135     *  - the first arg isn't the flattened component name of an existing provider:
12136     *    dump all providers whose component contains the first arg as a substring
12137     */
12138    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12139            int opti, boolean dumpAll) {
12140        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12141    }
12142
12143    static class ItemMatcher {
12144        ArrayList<ComponentName> components;
12145        ArrayList<String> strings;
12146        ArrayList<Integer> objects;
12147        boolean all;
12148
12149        ItemMatcher() {
12150            all = true;
12151        }
12152
12153        void build(String name) {
12154            ComponentName componentName = ComponentName.unflattenFromString(name);
12155            if (componentName != null) {
12156                if (components == null) {
12157                    components = new ArrayList<ComponentName>();
12158                }
12159                components.add(componentName);
12160                all = false;
12161            } else {
12162                int objectId = 0;
12163                // Not a '/' separated full component name; maybe an object ID?
12164                try {
12165                    objectId = Integer.parseInt(name, 16);
12166                    if (objects == null) {
12167                        objects = new ArrayList<Integer>();
12168                    }
12169                    objects.add(objectId);
12170                    all = false;
12171                } catch (RuntimeException e) {
12172                    // Not an integer; just do string match.
12173                    if (strings == null) {
12174                        strings = new ArrayList<String>();
12175                    }
12176                    strings.add(name);
12177                    all = false;
12178                }
12179            }
12180        }
12181
12182        int build(String[] args, int opti) {
12183            for (; opti<args.length; opti++) {
12184                String name = args[opti];
12185                if ("--".equals(name)) {
12186                    return opti+1;
12187                }
12188                build(name);
12189            }
12190            return opti;
12191        }
12192
12193        boolean match(Object object, ComponentName comp) {
12194            if (all) {
12195                return true;
12196            }
12197            if (components != null) {
12198                for (int i=0; i<components.size(); i++) {
12199                    if (components.get(i).equals(comp)) {
12200                        return true;
12201                    }
12202                }
12203            }
12204            if (objects != null) {
12205                for (int i=0; i<objects.size(); i++) {
12206                    if (System.identityHashCode(object) == objects.get(i)) {
12207                        return true;
12208                    }
12209                }
12210            }
12211            if (strings != null) {
12212                String flat = comp.flattenToString();
12213                for (int i=0; i<strings.size(); i++) {
12214                    if (flat.contains(strings.get(i))) {
12215                        return true;
12216                    }
12217                }
12218            }
12219            return false;
12220        }
12221    }
12222
12223    /**
12224     * There are three things that cmd can be:
12225     *  - a flattened component name that matches an existing activity
12226     *  - the cmd arg isn't the flattened component name of an existing activity:
12227     *    dump all activity whose component contains the cmd as a substring
12228     *  - A hex number of the ActivityRecord object instance.
12229     */
12230    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12231            int opti, boolean dumpAll) {
12232        ArrayList<ActivityRecord> activities;
12233
12234        synchronized (this) {
12235            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12236        }
12237
12238        if (activities.size() <= 0) {
12239            return false;
12240        }
12241
12242        String[] newArgs = new String[args.length - opti];
12243        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12244
12245        TaskRecord lastTask = null;
12246        boolean needSep = false;
12247        for (int i=activities.size()-1; i>=0; i--) {
12248            ActivityRecord r = activities.get(i);
12249            if (needSep) {
12250                pw.println();
12251            }
12252            needSep = true;
12253            synchronized (this) {
12254                if (lastTask != r.task) {
12255                    lastTask = r.task;
12256                    pw.print("TASK "); pw.print(lastTask.affinity);
12257                            pw.print(" id="); pw.println(lastTask.taskId);
12258                    if (dumpAll) {
12259                        lastTask.dump(pw, "  ");
12260                    }
12261                }
12262            }
12263            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12264        }
12265        return true;
12266    }
12267
12268    /**
12269     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12270     * there is a thread associated with the activity.
12271     */
12272    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12273            final ActivityRecord r, String[] args, boolean dumpAll) {
12274        String innerPrefix = prefix + "  ";
12275        synchronized (this) {
12276            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12277                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12278                    pw.print(" pid=");
12279                    if (r.app != null) pw.println(r.app.pid);
12280                    else pw.println("(not running)");
12281            if (dumpAll) {
12282                r.dump(pw, innerPrefix);
12283            }
12284        }
12285        if (r.app != null && r.app.thread != null) {
12286            // flush anything that is already in the PrintWriter since the thread is going
12287            // to write to the file descriptor directly
12288            pw.flush();
12289            try {
12290                TransferPipe tp = new TransferPipe();
12291                try {
12292                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12293                            r.appToken, innerPrefix, args);
12294                    tp.go(fd);
12295                } finally {
12296                    tp.kill();
12297                }
12298            } catch (IOException e) {
12299                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12300            } catch (RemoteException e) {
12301                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12302            }
12303        }
12304    }
12305
12306    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12307            int opti, boolean dumpAll, String dumpPackage) {
12308        boolean needSep = false;
12309        boolean onlyHistory = false;
12310        boolean printedAnything = false;
12311
12312        if ("history".equals(dumpPackage)) {
12313            if (opti < args.length && "-s".equals(args[opti])) {
12314                dumpAll = false;
12315            }
12316            onlyHistory = true;
12317            dumpPackage = null;
12318        }
12319
12320        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12321        if (!onlyHistory && dumpAll) {
12322            if (mRegisteredReceivers.size() > 0) {
12323                boolean printed = false;
12324                Iterator it = mRegisteredReceivers.values().iterator();
12325                while (it.hasNext()) {
12326                    ReceiverList r = (ReceiverList)it.next();
12327                    if (dumpPackage != null && (r.app == null ||
12328                            !dumpPackage.equals(r.app.info.packageName))) {
12329                        continue;
12330                    }
12331                    if (!printed) {
12332                        pw.println("  Registered Receivers:");
12333                        needSep = true;
12334                        printed = true;
12335                        printedAnything = true;
12336                    }
12337                    pw.print("  * "); pw.println(r);
12338                    r.dump(pw, "    ");
12339                }
12340            }
12341
12342            if (mReceiverResolver.dump(pw, needSep ?
12343                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12344                    "    ", dumpPackage, false)) {
12345                needSep = true;
12346                printedAnything = true;
12347            }
12348        }
12349
12350        for (BroadcastQueue q : mBroadcastQueues) {
12351            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12352            printedAnything |= needSep;
12353        }
12354
12355        needSep = true;
12356
12357        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12358            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12359                if (needSep) {
12360                    pw.println();
12361                }
12362                needSep = true;
12363                printedAnything = true;
12364                pw.print("  Sticky broadcasts for user ");
12365                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12366                StringBuilder sb = new StringBuilder(128);
12367                for (Map.Entry<String, ArrayList<Intent>> ent
12368                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12369                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12370                    if (dumpAll) {
12371                        pw.println(":");
12372                        ArrayList<Intent> intents = ent.getValue();
12373                        final int N = intents.size();
12374                        for (int i=0; i<N; i++) {
12375                            sb.setLength(0);
12376                            sb.append("    Intent: ");
12377                            intents.get(i).toShortString(sb, false, true, false, false);
12378                            pw.println(sb.toString());
12379                            Bundle bundle = intents.get(i).getExtras();
12380                            if (bundle != null) {
12381                                pw.print("      ");
12382                                pw.println(bundle.toString());
12383                            }
12384                        }
12385                    } else {
12386                        pw.println("");
12387                    }
12388                }
12389            }
12390        }
12391
12392        if (!onlyHistory && dumpAll) {
12393            pw.println();
12394            for (BroadcastQueue queue : mBroadcastQueues) {
12395                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12396                        + queue.mBroadcastsScheduled);
12397            }
12398            pw.println("  mHandler:");
12399            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12400            needSep = true;
12401            printedAnything = true;
12402        }
12403
12404        if (!printedAnything) {
12405            pw.println("  (nothing)");
12406        }
12407    }
12408
12409    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12410            int opti, boolean dumpAll, String dumpPackage) {
12411        boolean needSep;
12412        boolean printedAnything = false;
12413
12414        ItemMatcher matcher = new ItemMatcher();
12415        matcher.build(args, opti);
12416
12417        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12418
12419        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12420        printedAnything |= needSep;
12421
12422        if (mLaunchingProviders.size() > 0) {
12423            boolean printed = false;
12424            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12425                ContentProviderRecord r = mLaunchingProviders.get(i);
12426                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12427                    continue;
12428                }
12429                if (!printed) {
12430                    if (needSep) pw.println();
12431                    needSep = true;
12432                    pw.println("  Launching content providers:");
12433                    printed = true;
12434                    printedAnything = true;
12435                }
12436                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12437                        pw.println(r);
12438            }
12439        }
12440
12441        if (mGrantedUriPermissions.size() > 0) {
12442            boolean printed = false;
12443            int dumpUid = -2;
12444            if (dumpPackage != null) {
12445                try {
12446                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12447                } catch (NameNotFoundException e) {
12448                    dumpUid = -1;
12449                }
12450            }
12451            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12452                int uid = mGrantedUriPermissions.keyAt(i);
12453                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12454                    continue;
12455                }
12456                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12457                if (!printed) {
12458                    if (needSep) pw.println();
12459                    needSep = true;
12460                    pw.println("  Granted Uri Permissions:");
12461                    printed = true;
12462                    printedAnything = true;
12463                }
12464                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12465                for (UriPermission perm : perms.values()) {
12466                    pw.print("    "); pw.println(perm);
12467                    if (dumpAll) {
12468                        perm.dump(pw, "      ");
12469                    }
12470                }
12471            }
12472        }
12473
12474        if (!printedAnything) {
12475            pw.println("  (nothing)");
12476        }
12477    }
12478
12479    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12480            int opti, boolean dumpAll, String dumpPackage) {
12481        boolean printed = false;
12482
12483        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12484
12485        if (mIntentSenderRecords.size() > 0) {
12486            Iterator<WeakReference<PendingIntentRecord>> it
12487                    = mIntentSenderRecords.values().iterator();
12488            while (it.hasNext()) {
12489                WeakReference<PendingIntentRecord> ref = it.next();
12490                PendingIntentRecord rec = ref != null ? ref.get(): null;
12491                if (dumpPackage != null && (rec == null
12492                        || !dumpPackage.equals(rec.key.packageName))) {
12493                    continue;
12494                }
12495                printed = true;
12496                if (rec != null) {
12497                    pw.print("  * "); pw.println(rec);
12498                    if (dumpAll) {
12499                        rec.dump(pw, "    ");
12500                    }
12501                } else {
12502                    pw.print("  * "); pw.println(ref);
12503                }
12504            }
12505        }
12506
12507        if (!printed) {
12508            pw.println("  (nothing)");
12509        }
12510    }
12511
12512    private static final int dumpProcessList(PrintWriter pw,
12513            ActivityManagerService service, List list,
12514            String prefix, String normalLabel, String persistentLabel,
12515            String dumpPackage) {
12516        int numPers = 0;
12517        final int N = list.size()-1;
12518        for (int i=N; i>=0; i--) {
12519            ProcessRecord r = (ProcessRecord)list.get(i);
12520            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12521                continue;
12522            }
12523            pw.println(String.format("%s%s #%2d: %s",
12524                    prefix, (r.persistent ? persistentLabel : normalLabel),
12525                    i, r.toString()));
12526            if (r.persistent) {
12527                numPers++;
12528            }
12529        }
12530        return numPers;
12531    }
12532
12533    private static final boolean dumpProcessOomList(PrintWriter pw,
12534            ActivityManagerService service, List<ProcessRecord> origList,
12535            String prefix, String normalLabel, String persistentLabel,
12536            boolean inclDetails, String dumpPackage) {
12537
12538        ArrayList<Pair<ProcessRecord, Integer>> list
12539                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12540        for (int i=0; i<origList.size(); i++) {
12541            ProcessRecord r = origList.get(i);
12542            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12543                continue;
12544            }
12545            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12546        }
12547
12548        if (list.size() <= 0) {
12549            return false;
12550        }
12551
12552        Comparator<Pair<ProcessRecord, Integer>> comparator
12553                = new Comparator<Pair<ProcessRecord, Integer>>() {
12554            @Override
12555            public int compare(Pair<ProcessRecord, Integer> object1,
12556                    Pair<ProcessRecord, Integer> object2) {
12557                if (object1.first.setAdj != object2.first.setAdj) {
12558                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12559                }
12560                if (object1.second.intValue() != object2.second.intValue()) {
12561                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12562                }
12563                return 0;
12564            }
12565        };
12566
12567        Collections.sort(list, comparator);
12568
12569        final long curRealtime = SystemClock.elapsedRealtime();
12570        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12571        final long curUptime = SystemClock.uptimeMillis();
12572        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12573
12574        for (int i=list.size()-1; i>=0; i--) {
12575            ProcessRecord r = list.get(i).first;
12576            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12577            char schedGroup;
12578            switch (r.setSchedGroup) {
12579                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12580                    schedGroup = 'B';
12581                    break;
12582                case Process.THREAD_GROUP_DEFAULT:
12583                    schedGroup = 'F';
12584                    break;
12585                default:
12586                    schedGroup = '?';
12587                    break;
12588            }
12589            char foreground;
12590            if (r.foregroundActivities) {
12591                foreground = 'A';
12592            } else if (r.foregroundServices) {
12593                foreground = 'S';
12594            } else {
12595                foreground = ' ';
12596            }
12597            String procState = ProcessList.makeProcStateString(r.curProcState);
12598            pw.print(prefix);
12599            pw.print(r.persistent ? persistentLabel : normalLabel);
12600            pw.print(" #");
12601            int num = (origList.size()-1)-list.get(i).second;
12602            if (num < 10) pw.print(' ');
12603            pw.print(num);
12604            pw.print(": ");
12605            pw.print(oomAdj);
12606            pw.print(' ');
12607            pw.print(schedGroup);
12608            pw.print('/');
12609            pw.print(foreground);
12610            pw.print('/');
12611            pw.print(procState);
12612            pw.print(" trm:");
12613            if (r.trimMemoryLevel < 10) pw.print(' ');
12614            pw.print(r.trimMemoryLevel);
12615            pw.print(' ');
12616            pw.print(r.toShortString());
12617            pw.print(" (");
12618            pw.print(r.adjType);
12619            pw.println(')');
12620            if (r.adjSource != null || r.adjTarget != null) {
12621                pw.print(prefix);
12622                pw.print("    ");
12623                if (r.adjTarget instanceof ComponentName) {
12624                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12625                } else if (r.adjTarget != null) {
12626                    pw.print(r.adjTarget.toString());
12627                } else {
12628                    pw.print("{null}");
12629                }
12630                pw.print("<=");
12631                if (r.adjSource instanceof ProcessRecord) {
12632                    pw.print("Proc{");
12633                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12634                    pw.println("}");
12635                } else if (r.adjSource != null) {
12636                    pw.println(r.adjSource.toString());
12637                } else {
12638                    pw.println("{null}");
12639                }
12640            }
12641            if (inclDetails) {
12642                pw.print(prefix);
12643                pw.print("    ");
12644                pw.print("oom: max="); pw.print(r.maxAdj);
12645                pw.print(" curRaw="); pw.print(r.curRawAdj);
12646                pw.print(" setRaw="); pw.print(r.setRawAdj);
12647                pw.print(" cur="); pw.print(r.curAdj);
12648                pw.print(" set="); pw.println(r.setAdj);
12649                pw.print(prefix);
12650                pw.print("    ");
12651                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12652                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12653                pw.print(" lastPss="); pw.print(r.lastPss);
12654                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12655                pw.print(prefix);
12656                pw.print("    ");
12657                pw.print("cached="); pw.print(r.cached);
12658                pw.print(" empty="); pw.print(r.empty);
12659                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12660
12661                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12662                    if (r.lastWakeTime != 0) {
12663                        long wtime;
12664                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12665                        synchronized (stats) {
12666                            wtime = stats.getProcessWakeTime(r.info.uid,
12667                                    r.pid, curRealtime);
12668                        }
12669                        long timeUsed = wtime - r.lastWakeTime;
12670                        pw.print(prefix);
12671                        pw.print("    ");
12672                        pw.print("keep awake over ");
12673                        TimeUtils.formatDuration(realtimeSince, pw);
12674                        pw.print(" used ");
12675                        TimeUtils.formatDuration(timeUsed, pw);
12676                        pw.print(" (");
12677                        pw.print((timeUsed*100)/realtimeSince);
12678                        pw.println("%)");
12679                    }
12680                    if (r.lastCpuTime != 0) {
12681                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12682                        pw.print(prefix);
12683                        pw.print("    ");
12684                        pw.print("run cpu over ");
12685                        TimeUtils.formatDuration(uptimeSince, pw);
12686                        pw.print(" used ");
12687                        TimeUtils.formatDuration(timeUsed, pw);
12688                        pw.print(" (");
12689                        pw.print((timeUsed*100)/uptimeSince);
12690                        pw.println("%)");
12691                    }
12692                }
12693            }
12694        }
12695        return true;
12696    }
12697
12698    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12699        ArrayList<ProcessRecord> procs;
12700        synchronized (this) {
12701            if (args != null && args.length > start
12702                    && args[start].charAt(0) != '-') {
12703                procs = new ArrayList<ProcessRecord>();
12704                int pid = -1;
12705                try {
12706                    pid = Integer.parseInt(args[start]);
12707                } catch (NumberFormatException e) {
12708                }
12709                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12710                    ProcessRecord proc = mLruProcesses.get(i);
12711                    if (proc.pid == pid) {
12712                        procs.add(proc);
12713                    } else if (proc.processName.equals(args[start])) {
12714                        procs.add(proc);
12715                    }
12716                }
12717                if (procs.size() <= 0) {
12718                    return null;
12719                }
12720            } else {
12721                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12722            }
12723        }
12724        return procs;
12725    }
12726
12727    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12728            PrintWriter pw, String[] args) {
12729        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12730        if (procs == null) {
12731            pw.println("No process found for: " + args[0]);
12732            return;
12733        }
12734
12735        long uptime = SystemClock.uptimeMillis();
12736        long realtime = SystemClock.elapsedRealtime();
12737        pw.println("Applications Graphics Acceleration Info:");
12738        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12739
12740        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12741            ProcessRecord r = procs.get(i);
12742            if (r.thread != null) {
12743                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12744                pw.flush();
12745                try {
12746                    TransferPipe tp = new TransferPipe();
12747                    try {
12748                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12749                        tp.go(fd);
12750                    } finally {
12751                        tp.kill();
12752                    }
12753                } catch (IOException e) {
12754                    pw.println("Failure while dumping the app: " + r);
12755                    pw.flush();
12756                } catch (RemoteException e) {
12757                    pw.println("Got a RemoteException while dumping the app " + r);
12758                    pw.flush();
12759                }
12760            }
12761        }
12762    }
12763
12764    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12765        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12766        if (procs == null) {
12767            pw.println("No process found for: " + args[0]);
12768            return;
12769        }
12770
12771        pw.println("Applications Database Info:");
12772
12773        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12774            ProcessRecord r = procs.get(i);
12775            if (r.thread != null) {
12776                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12777                pw.flush();
12778                try {
12779                    TransferPipe tp = new TransferPipe();
12780                    try {
12781                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12782                        tp.go(fd);
12783                    } finally {
12784                        tp.kill();
12785                    }
12786                } catch (IOException e) {
12787                    pw.println("Failure while dumping the app: " + r);
12788                    pw.flush();
12789                } catch (RemoteException e) {
12790                    pw.println("Got a RemoteException while dumping the app " + r);
12791                    pw.flush();
12792                }
12793            }
12794        }
12795    }
12796
12797    final static class MemItem {
12798        final boolean isProc;
12799        final String label;
12800        final String shortLabel;
12801        final long pss;
12802        final int id;
12803        final boolean hasActivities;
12804        ArrayList<MemItem> subitems;
12805
12806        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12807                boolean _hasActivities) {
12808            isProc = true;
12809            label = _label;
12810            shortLabel = _shortLabel;
12811            pss = _pss;
12812            id = _id;
12813            hasActivities = _hasActivities;
12814        }
12815
12816        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12817            isProc = false;
12818            label = _label;
12819            shortLabel = _shortLabel;
12820            pss = _pss;
12821            id = _id;
12822            hasActivities = false;
12823        }
12824    }
12825
12826    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12827            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12828        if (sort && !isCompact) {
12829            Collections.sort(items, new Comparator<MemItem>() {
12830                @Override
12831                public int compare(MemItem lhs, MemItem rhs) {
12832                    if (lhs.pss < rhs.pss) {
12833                        return 1;
12834                    } else if (lhs.pss > rhs.pss) {
12835                        return -1;
12836                    }
12837                    return 0;
12838                }
12839            });
12840        }
12841
12842        for (int i=0; i<items.size(); i++) {
12843            MemItem mi = items.get(i);
12844            if (!isCompact) {
12845                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12846            } else if (mi.isProc) {
12847                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12848                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12849                pw.println(mi.hasActivities ? ",a" : ",e");
12850            } else {
12851                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12852                pw.println(mi.pss);
12853            }
12854            if (mi.subitems != null) {
12855                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12856                        true, isCompact);
12857            }
12858        }
12859    }
12860
12861    // These are in KB.
12862    static final long[] DUMP_MEM_BUCKETS = new long[] {
12863        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12864        120*1024, 160*1024, 200*1024,
12865        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12866        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12867    };
12868
12869    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12870            boolean stackLike) {
12871        int start = label.lastIndexOf('.');
12872        if (start >= 0) start++;
12873        else start = 0;
12874        int end = label.length();
12875        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12876            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12877                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12878                out.append(bucket);
12879                out.append(stackLike ? "MB." : "MB ");
12880                out.append(label, start, end);
12881                return;
12882            }
12883        }
12884        out.append(memKB/1024);
12885        out.append(stackLike ? "MB." : "MB ");
12886        out.append(label, start, end);
12887    }
12888
12889    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12890            ProcessList.NATIVE_ADJ,
12891            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12892            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12893            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12894            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12895            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12896    };
12897    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12898            "Native",
12899            "System", "Persistent", "Foreground",
12900            "Visible", "Perceptible",
12901            "Heavy Weight", "Backup",
12902            "A Services", "Home",
12903            "Previous", "B Services", "Cached"
12904    };
12905    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12906            "native",
12907            "sys", "pers", "fore",
12908            "vis", "percept",
12909            "heavy", "backup",
12910            "servicea", "home",
12911            "prev", "serviceb", "cached"
12912    };
12913
12914    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12915            long realtime, boolean isCheckinRequest, boolean isCompact) {
12916        if (isCheckinRequest || isCompact) {
12917            // short checkin version
12918            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12919        } else {
12920            pw.println("Applications Memory Usage (kB):");
12921            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12922        }
12923    }
12924
12925    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12926            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12927        boolean dumpDetails = false;
12928        boolean dumpFullDetails = false;
12929        boolean dumpDalvik = false;
12930        boolean oomOnly = false;
12931        boolean isCompact = false;
12932        boolean localOnly = false;
12933
12934        int opti = 0;
12935        while (opti < args.length) {
12936            String opt = args[opti];
12937            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12938                break;
12939            }
12940            opti++;
12941            if ("-a".equals(opt)) {
12942                dumpDetails = true;
12943                dumpFullDetails = true;
12944                dumpDalvik = true;
12945            } else if ("-d".equals(opt)) {
12946                dumpDalvik = true;
12947            } else if ("-c".equals(opt)) {
12948                isCompact = true;
12949            } else if ("--oom".equals(opt)) {
12950                oomOnly = true;
12951            } else if ("--local".equals(opt)) {
12952                localOnly = true;
12953            } else if ("-h".equals(opt)) {
12954                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12955                pw.println("  -a: include all available information for each process.");
12956                pw.println("  -d: include dalvik details when dumping process details.");
12957                pw.println("  -c: dump in a compact machine-parseable representation.");
12958                pw.println("  --oom: only show processes organized by oom adj.");
12959                pw.println("  --local: only collect details locally, don't call process.");
12960                pw.println("If [process] is specified it can be the name or ");
12961                pw.println("pid of a specific process to dump.");
12962                return;
12963            } else {
12964                pw.println("Unknown argument: " + opt + "; use -h for help");
12965            }
12966        }
12967
12968        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12969        long uptime = SystemClock.uptimeMillis();
12970        long realtime = SystemClock.elapsedRealtime();
12971        final long[] tmpLong = new long[1];
12972
12973        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12974        if (procs == null) {
12975            // No Java processes.  Maybe they want to print a native process.
12976            if (args != null && args.length > opti
12977                    && args[opti].charAt(0) != '-') {
12978                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12979                        = new ArrayList<ProcessCpuTracker.Stats>();
12980                updateCpuStatsNow();
12981                int findPid = -1;
12982                try {
12983                    findPid = Integer.parseInt(args[opti]);
12984                } catch (NumberFormatException e) {
12985                }
12986                synchronized (mProcessCpuThread) {
12987                    final int N = mProcessCpuTracker.countStats();
12988                    for (int i=0; i<N; i++) {
12989                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12990                        if (st.pid == findPid || (st.baseName != null
12991                                && st.baseName.equals(args[opti]))) {
12992                            nativeProcs.add(st);
12993                        }
12994                    }
12995                }
12996                if (nativeProcs.size() > 0) {
12997                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12998                            isCompact);
12999                    Debug.MemoryInfo mi = null;
13000                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13001                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13002                        final int pid = r.pid;
13003                        if (!isCheckinRequest && dumpDetails) {
13004                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13005                        }
13006                        if (mi == null) {
13007                            mi = new Debug.MemoryInfo();
13008                        }
13009                        if (dumpDetails || (!brief && !oomOnly)) {
13010                            Debug.getMemoryInfo(pid, mi);
13011                        } else {
13012                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13013                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13014                        }
13015                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13016                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13017                        if (isCheckinRequest) {
13018                            pw.println();
13019                        }
13020                    }
13021                    return;
13022                }
13023            }
13024            pw.println("No process found for: " + args[opti]);
13025            return;
13026        }
13027
13028        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13029            dumpDetails = true;
13030        }
13031
13032        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13033
13034        String[] innerArgs = new String[args.length-opti];
13035        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13036
13037        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13038        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13039        long nativePss=0, dalvikPss=0, otherPss=0;
13040        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13041
13042        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13043        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13044                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13045
13046        long totalPss = 0;
13047        long cachedPss = 0;
13048
13049        Debug.MemoryInfo mi = null;
13050        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13051            final ProcessRecord r = procs.get(i);
13052            final IApplicationThread thread;
13053            final int pid;
13054            final int oomAdj;
13055            final boolean hasActivities;
13056            synchronized (this) {
13057                thread = r.thread;
13058                pid = r.pid;
13059                oomAdj = r.getSetAdjWithServices();
13060                hasActivities = r.activities.size() > 0;
13061            }
13062            if (thread != null) {
13063                if (!isCheckinRequest && dumpDetails) {
13064                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13065                }
13066                if (mi == null) {
13067                    mi = new Debug.MemoryInfo();
13068                }
13069                if (dumpDetails || (!brief && !oomOnly)) {
13070                    Debug.getMemoryInfo(pid, mi);
13071                } else {
13072                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13073                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13074                }
13075                if (dumpDetails) {
13076                    if (localOnly) {
13077                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13078                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13079                        if (isCheckinRequest) {
13080                            pw.println();
13081                        }
13082                    } else {
13083                        try {
13084                            pw.flush();
13085                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13086                                    dumpDalvik, innerArgs);
13087                        } catch (RemoteException e) {
13088                            if (!isCheckinRequest) {
13089                                pw.println("Got RemoteException!");
13090                                pw.flush();
13091                            }
13092                        }
13093                    }
13094                }
13095
13096                final long myTotalPss = mi.getTotalPss();
13097                final long myTotalUss = mi.getTotalUss();
13098
13099                synchronized (this) {
13100                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13101                        // Record this for posterity if the process has been stable.
13102                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13103                    }
13104                }
13105
13106                if (!isCheckinRequest && mi != null) {
13107                    totalPss += myTotalPss;
13108                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13109                            (hasActivities ? " / activities)" : ")"),
13110                            r.processName, myTotalPss, pid, hasActivities);
13111                    procMems.add(pssItem);
13112                    procMemsMap.put(pid, pssItem);
13113
13114                    nativePss += mi.nativePss;
13115                    dalvikPss += mi.dalvikPss;
13116                    otherPss += mi.otherPss;
13117                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13118                        long mem = mi.getOtherPss(j);
13119                        miscPss[j] += mem;
13120                        otherPss -= mem;
13121                    }
13122
13123                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13124                        cachedPss += myTotalPss;
13125                    }
13126
13127                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13128                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13129                                || oomIndex == (oomPss.length-1)) {
13130                            oomPss[oomIndex] += myTotalPss;
13131                            if (oomProcs[oomIndex] == null) {
13132                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13133                            }
13134                            oomProcs[oomIndex].add(pssItem);
13135                            break;
13136                        }
13137                    }
13138                }
13139            }
13140        }
13141
13142        long nativeProcTotalPss = 0;
13143
13144        if (!isCheckinRequest && procs.size() > 1) {
13145            // If we are showing aggregations, also look for native processes to
13146            // include so that our aggregations are more accurate.
13147            updateCpuStatsNow();
13148            synchronized (mProcessCpuThread) {
13149                final int N = mProcessCpuTracker.countStats();
13150                for (int i=0; i<N; i++) {
13151                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13152                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13153                        if (mi == null) {
13154                            mi = new Debug.MemoryInfo();
13155                        }
13156                        if (!brief && !oomOnly) {
13157                            Debug.getMemoryInfo(st.pid, mi);
13158                        } else {
13159                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13160                            mi.nativePrivateDirty = (int)tmpLong[0];
13161                        }
13162
13163                        final long myTotalPss = mi.getTotalPss();
13164                        totalPss += myTotalPss;
13165                        nativeProcTotalPss += myTotalPss;
13166
13167                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13168                                st.name, myTotalPss, st.pid, false);
13169                        procMems.add(pssItem);
13170
13171                        nativePss += mi.nativePss;
13172                        dalvikPss += mi.dalvikPss;
13173                        otherPss += mi.otherPss;
13174                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13175                            long mem = mi.getOtherPss(j);
13176                            miscPss[j] += mem;
13177                            otherPss -= mem;
13178                        }
13179                        oomPss[0] += myTotalPss;
13180                        if (oomProcs[0] == null) {
13181                            oomProcs[0] = new ArrayList<MemItem>();
13182                        }
13183                        oomProcs[0].add(pssItem);
13184                    }
13185                }
13186            }
13187
13188            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13189
13190            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13191            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13192            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13193            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13194                String label = Debug.MemoryInfo.getOtherLabel(j);
13195                catMems.add(new MemItem(label, label, miscPss[j], j));
13196            }
13197
13198            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13199            for (int j=0; j<oomPss.length; j++) {
13200                if (oomPss[j] != 0) {
13201                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13202                            : DUMP_MEM_OOM_LABEL[j];
13203                    MemItem item = new MemItem(label, label, oomPss[j],
13204                            DUMP_MEM_OOM_ADJ[j]);
13205                    item.subitems = oomProcs[j];
13206                    oomMems.add(item);
13207                }
13208            }
13209
13210            if (!brief && !oomOnly && !isCompact) {
13211                pw.println();
13212                pw.println("Total PSS by process:");
13213                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13214                pw.println();
13215            }
13216            if (!isCompact) {
13217                pw.println("Total PSS by OOM adjustment:");
13218            }
13219            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13220            if (!brief && !oomOnly) {
13221                PrintWriter out = categoryPw != null ? categoryPw : pw;
13222                if (!isCompact) {
13223                    out.println();
13224                    out.println("Total PSS by category:");
13225                }
13226                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13227            }
13228            if (!isCompact) {
13229                pw.println();
13230            }
13231            MemInfoReader memInfo = new MemInfoReader();
13232            memInfo.readMemInfo();
13233            if (nativeProcTotalPss > 0) {
13234                synchronized (this) {
13235                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13236                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13237                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13238                            nativeProcTotalPss);
13239                }
13240            }
13241            if (!brief) {
13242                if (!isCompact) {
13243                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13244                    pw.print(" kB (status ");
13245                    switch (mLastMemoryLevel) {
13246                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13247                            pw.println("normal)");
13248                            break;
13249                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13250                            pw.println("moderate)");
13251                            break;
13252                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13253                            pw.println("low)");
13254                            break;
13255                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13256                            pw.println("critical)");
13257                            break;
13258                        default:
13259                            pw.print(mLastMemoryLevel);
13260                            pw.println(")");
13261                            break;
13262                    }
13263                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13264                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13265                            pw.print(cachedPss); pw.print(" cached pss + ");
13266                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13267                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13268                } else {
13269                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13270                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13271                            + memInfo.getFreeSizeKb()); pw.print(",");
13272                    pw.println(totalPss - cachedPss);
13273                }
13274            }
13275            if (!isCompact) {
13276                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13277                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13278                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13279                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13280                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13281                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13282                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13283                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13284                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13285                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13286                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13287            }
13288            if (!brief) {
13289                if (memInfo.getZramTotalSizeKb() != 0) {
13290                    if (!isCompact) {
13291                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13292                                pw.print(" kB physical used for ");
13293                                pw.print(memInfo.getSwapTotalSizeKb()
13294                                        - memInfo.getSwapFreeSizeKb());
13295                                pw.print(" kB in swap (");
13296                                pw.print(memInfo.getSwapTotalSizeKb());
13297                                pw.println(" kB total swap)");
13298                    } else {
13299                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13300                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13301                                pw.println(memInfo.getSwapFreeSizeKb());
13302                    }
13303                }
13304                final int[] SINGLE_LONG_FORMAT = new int[] {
13305                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13306                };
13307                long[] longOut = new long[1];
13308                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13309                        SINGLE_LONG_FORMAT, null, longOut, null);
13310                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13311                longOut[0] = 0;
13312                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13313                        SINGLE_LONG_FORMAT, null, longOut, null);
13314                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13315                longOut[0] = 0;
13316                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13317                        SINGLE_LONG_FORMAT, null, longOut, null);
13318                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13319                longOut[0] = 0;
13320                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13321                        SINGLE_LONG_FORMAT, null, longOut, null);
13322                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13323                if (!isCompact) {
13324                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13325                        pw.print("      KSM: "); pw.print(sharing);
13326                                pw.print(" kB saved from shared ");
13327                                pw.print(shared); pw.println(" kB");
13328                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13329                                pw.print(voltile); pw.println(" kB volatile");
13330                    }
13331                    pw.print("   Tuning: ");
13332                    pw.print(ActivityManager.staticGetMemoryClass());
13333                    pw.print(" (large ");
13334                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13335                    pw.print("), oom ");
13336                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13337                    pw.print(" kB");
13338                    pw.print(", restore limit ");
13339                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13340                    pw.print(" kB");
13341                    if (ActivityManager.isLowRamDeviceStatic()) {
13342                        pw.print(" (low-ram)");
13343                    }
13344                    if (ActivityManager.isHighEndGfx()) {
13345                        pw.print(" (high-end-gfx)");
13346                    }
13347                    pw.println();
13348                } else {
13349                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13350                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13351                    pw.println(voltile);
13352                    pw.print("tuning,");
13353                    pw.print(ActivityManager.staticGetMemoryClass());
13354                    pw.print(',');
13355                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13356                    pw.print(',');
13357                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13358                    if (ActivityManager.isLowRamDeviceStatic()) {
13359                        pw.print(",low-ram");
13360                    }
13361                    if (ActivityManager.isHighEndGfx()) {
13362                        pw.print(",high-end-gfx");
13363                    }
13364                    pw.println();
13365                }
13366            }
13367        }
13368    }
13369
13370    /**
13371     * Searches array of arguments for the specified string
13372     * @param args array of argument strings
13373     * @param value value to search for
13374     * @return true if the value is contained in the array
13375     */
13376    private static boolean scanArgs(String[] args, String value) {
13377        if (args != null) {
13378            for (String arg : args) {
13379                if (value.equals(arg)) {
13380                    return true;
13381                }
13382            }
13383        }
13384        return false;
13385    }
13386
13387    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13388            ContentProviderRecord cpr, boolean always) {
13389        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13390
13391        if (!inLaunching || always) {
13392            synchronized (cpr) {
13393                cpr.launchingApp = null;
13394                cpr.notifyAll();
13395            }
13396            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13397            String names[] = cpr.info.authority.split(";");
13398            for (int j = 0; j < names.length; j++) {
13399                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13400            }
13401        }
13402
13403        for (int i=0; i<cpr.connections.size(); i++) {
13404            ContentProviderConnection conn = cpr.connections.get(i);
13405            if (conn.waiting) {
13406                // If this connection is waiting for the provider, then we don't
13407                // need to mess with its process unless we are always removing
13408                // or for some reason the provider is not currently launching.
13409                if (inLaunching && !always) {
13410                    continue;
13411                }
13412            }
13413            ProcessRecord capp = conn.client;
13414            conn.dead = true;
13415            if (conn.stableCount > 0) {
13416                if (!capp.persistent && capp.thread != null
13417                        && capp.pid != 0
13418                        && capp.pid != MY_PID) {
13419                    killUnneededProcessLocked(capp, "depends on provider "
13420                            + cpr.name.flattenToShortString()
13421                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13422                }
13423            } else if (capp.thread != null && conn.provider.provider != null) {
13424                try {
13425                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13426                } catch (RemoteException e) {
13427                }
13428                // In the protocol here, we don't expect the client to correctly
13429                // clean up this connection, we'll just remove it.
13430                cpr.connections.remove(i);
13431                conn.client.conProviders.remove(conn);
13432            }
13433        }
13434
13435        if (inLaunching && always) {
13436            mLaunchingProviders.remove(cpr);
13437        }
13438        return inLaunching;
13439    }
13440
13441    /**
13442     * Main code for cleaning up a process when it has gone away.  This is
13443     * called both as a result of the process dying, or directly when stopping
13444     * a process when running in single process mode.
13445     */
13446    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13447            boolean restarting, boolean allowRestart, int index) {
13448        if (index >= 0) {
13449            removeLruProcessLocked(app);
13450            ProcessList.remove(app.pid);
13451        }
13452
13453        mProcessesToGc.remove(app);
13454        mPendingPssProcesses.remove(app);
13455
13456        // Dismiss any open dialogs.
13457        if (app.crashDialog != null && !app.forceCrashReport) {
13458            app.crashDialog.dismiss();
13459            app.crashDialog = null;
13460        }
13461        if (app.anrDialog != null) {
13462            app.anrDialog.dismiss();
13463            app.anrDialog = null;
13464        }
13465        if (app.waitDialog != null) {
13466            app.waitDialog.dismiss();
13467            app.waitDialog = null;
13468        }
13469
13470        app.crashing = false;
13471        app.notResponding = false;
13472
13473        app.resetPackageList(mProcessStats);
13474        app.unlinkDeathRecipient();
13475        app.makeInactive(mProcessStats);
13476        app.waitingToKill = null;
13477        app.forcingToForeground = null;
13478        updateProcessForegroundLocked(app, false, false);
13479        app.foregroundActivities = false;
13480        app.hasShownUi = false;
13481        app.treatLikeActivity = false;
13482        app.hasAboveClient = false;
13483        app.hasClientActivities = false;
13484
13485        mServices.killServicesLocked(app, allowRestart);
13486
13487        boolean restart = false;
13488
13489        // Remove published content providers.
13490        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13491            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13492            final boolean always = app.bad || !allowRestart;
13493            if (removeDyingProviderLocked(app, cpr, always) || always) {
13494                // We left the provider in the launching list, need to
13495                // restart it.
13496                restart = true;
13497            }
13498
13499            cpr.provider = null;
13500            cpr.proc = null;
13501        }
13502        app.pubProviders.clear();
13503
13504        // Take care of any launching providers waiting for this process.
13505        if (checkAppInLaunchingProvidersLocked(app, false)) {
13506            restart = true;
13507        }
13508
13509        // Unregister from connected content providers.
13510        if (!app.conProviders.isEmpty()) {
13511            for (int i=0; i<app.conProviders.size(); i++) {
13512                ContentProviderConnection conn = app.conProviders.get(i);
13513                conn.provider.connections.remove(conn);
13514            }
13515            app.conProviders.clear();
13516        }
13517
13518        // At this point there may be remaining entries in mLaunchingProviders
13519        // where we were the only one waiting, so they are no longer of use.
13520        // Look for these and clean up if found.
13521        // XXX Commented out for now.  Trying to figure out a way to reproduce
13522        // the actual situation to identify what is actually going on.
13523        if (false) {
13524            for (int i=0; i<mLaunchingProviders.size(); i++) {
13525                ContentProviderRecord cpr = (ContentProviderRecord)
13526                        mLaunchingProviders.get(i);
13527                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13528                    synchronized (cpr) {
13529                        cpr.launchingApp = null;
13530                        cpr.notifyAll();
13531                    }
13532                }
13533            }
13534        }
13535
13536        skipCurrentReceiverLocked(app);
13537
13538        // Unregister any receivers.
13539        for (int i=app.receivers.size()-1; i>=0; i--) {
13540            removeReceiverLocked(app.receivers.valueAt(i));
13541        }
13542        app.receivers.clear();
13543
13544        // If the app is undergoing backup, tell the backup manager about it
13545        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13546            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13547                    + mBackupTarget.appInfo + " died during backup");
13548            try {
13549                IBackupManager bm = IBackupManager.Stub.asInterface(
13550                        ServiceManager.getService(Context.BACKUP_SERVICE));
13551                bm.agentDisconnected(app.info.packageName);
13552            } catch (RemoteException e) {
13553                // can't happen; backup manager is local
13554            }
13555        }
13556
13557        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13558            ProcessChangeItem item = mPendingProcessChanges.get(i);
13559            if (item.pid == app.pid) {
13560                mPendingProcessChanges.remove(i);
13561                mAvailProcessChanges.add(item);
13562            }
13563        }
13564        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13565
13566        // If the caller is restarting this app, then leave it in its
13567        // current lists and let the caller take care of it.
13568        if (restarting) {
13569            return;
13570        }
13571
13572        if (!app.persistent || app.isolated) {
13573            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13574                    "Removing non-persistent process during cleanup: " + app);
13575            mProcessNames.remove(app.processName, app.uid);
13576            mIsolatedProcesses.remove(app.uid);
13577            if (mHeavyWeightProcess == app) {
13578                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13579                        mHeavyWeightProcess.userId, 0));
13580                mHeavyWeightProcess = null;
13581            }
13582        } else if (!app.removed) {
13583            // This app is persistent, so we need to keep its record around.
13584            // If it is not already on the pending app list, add it there
13585            // and start a new process for it.
13586            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13587                mPersistentStartingProcesses.add(app);
13588                restart = true;
13589            }
13590        }
13591        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13592                "Clean-up removing on hold: " + app);
13593        mProcessesOnHold.remove(app);
13594
13595        if (app == mHomeProcess) {
13596            mHomeProcess = null;
13597        }
13598        if (app == mPreviousProcess) {
13599            mPreviousProcess = null;
13600        }
13601
13602        if (restart && !app.isolated) {
13603            // We have components that still need to be running in the
13604            // process, so re-launch it.
13605            mProcessNames.put(app.processName, app.uid, app);
13606            startProcessLocked(app, "restart", app.processName);
13607        } else if (app.pid > 0 && app.pid != MY_PID) {
13608            // Goodbye!
13609            boolean removed;
13610            synchronized (mPidsSelfLocked) {
13611                mPidsSelfLocked.remove(app.pid);
13612                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13613            }
13614            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13615            if (app.isolated) {
13616                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13617            }
13618            app.setPid(0);
13619        }
13620    }
13621
13622    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13623        // Look through the content providers we are waiting to have launched,
13624        // and if any run in this process then either schedule a restart of
13625        // the process or kill the client waiting for it if this process has
13626        // gone bad.
13627        int NL = mLaunchingProviders.size();
13628        boolean restart = false;
13629        for (int i=0; i<NL; i++) {
13630            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13631            if (cpr.launchingApp == app) {
13632                if (!alwaysBad && !app.bad) {
13633                    restart = true;
13634                } else {
13635                    removeDyingProviderLocked(app, cpr, true);
13636                    // cpr should have been removed from mLaunchingProviders
13637                    NL = mLaunchingProviders.size();
13638                    i--;
13639                }
13640            }
13641        }
13642        return restart;
13643    }
13644
13645    // =========================================================
13646    // SERVICES
13647    // =========================================================
13648
13649    @Override
13650    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13651            int flags) {
13652        enforceNotIsolatedCaller("getServices");
13653        synchronized (this) {
13654            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13655        }
13656    }
13657
13658    @Override
13659    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13660        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13661        synchronized (this) {
13662            return mServices.getRunningServiceControlPanelLocked(name);
13663        }
13664    }
13665
13666    @Override
13667    public ComponentName startService(IApplicationThread caller, Intent service,
13668            String resolvedType, int userId) {
13669        enforceNotIsolatedCaller("startService");
13670        // Refuse possible leaked file descriptors
13671        if (service != null && service.hasFileDescriptors() == true) {
13672            throw new IllegalArgumentException("File descriptors passed in Intent");
13673        }
13674
13675        if (DEBUG_SERVICE)
13676            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13677        synchronized(this) {
13678            final int callingPid = Binder.getCallingPid();
13679            final int callingUid = Binder.getCallingUid();
13680            final long origId = Binder.clearCallingIdentity();
13681            ComponentName res = mServices.startServiceLocked(caller, service,
13682                    resolvedType, callingPid, callingUid, userId);
13683            Binder.restoreCallingIdentity(origId);
13684            return res;
13685        }
13686    }
13687
13688    ComponentName startServiceInPackage(int uid,
13689            Intent service, String resolvedType, int userId) {
13690        synchronized(this) {
13691            if (DEBUG_SERVICE)
13692                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13693            final long origId = Binder.clearCallingIdentity();
13694            ComponentName res = mServices.startServiceLocked(null, service,
13695                    resolvedType, -1, uid, userId);
13696            Binder.restoreCallingIdentity(origId);
13697            return res;
13698        }
13699    }
13700
13701    @Override
13702    public int stopService(IApplicationThread caller, Intent service,
13703            String resolvedType, int userId) {
13704        enforceNotIsolatedCaller("stopService");
13705        // Refuse possible leaked file descriptors
13706        if (service != null && service.hasFileDescriptors() == true) {
13707            throw new IllegalArgumentException("File descriptors passed in Intent");
13708        }
13709
13710        synchronized(this) {
13711            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13712        }
13713    }
13714
13715    @Override
13716    public IBinder peekService(Intent service, String resolvedType) {
13717        enforceNotIsolatedCaller("peekService");
13718        // Refuse possible leaked file descriptors
13719        if (service != null && service.hasFileDescriptors() == true) {
13720            throw new IllegalArgumentException("File descriptors passed in Intent");
13721        }
13722        synchronized(this) {
13723            return mServices.peekServiceLocked(service, resolvedType);
13724        }
13725    }
13726
13727    @Override
13728    public boolean stopServiceToken(ComponentName className, IBinder token,
13729            int startId) {
13730        synchronized(this) {
13731            return mServices.stopServiceTokenLocked(className, token, startId);
13732        }
13733    }
13734
13735    @Override
13736    public void setServiceForeground(ComponentName className, IBinder token,
13737            int id, Notification notification, boolean removeNotification) {
13738        synchronized(this) {
13739            mServices.setServiceForegroundLocked(className, token, id, notification,
13740                    removeNotification);
13741        }
13742    }
13743
13744    @Override
13745    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13746            boolean requireFull, String name, String callerPackage) {
13747        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13748                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13749    }
13750
13751    int unsafeConvertIncomingUser(int userId) {
13752        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13753                ? mCurrentUserId : userId;
13754    }
13755
13756    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13757            int allowMode, String name, String callerPackage) {
13758        final int callingUserId = UserHandle.getUserId(callingUid);
13759        if (callingUserId == userId) {
13760            return userId;
13761        }
13762
13763        // Note that we may be accessing mCurrentUserId outside of a lock...
13764        // shouldn't be a big deal, if this is being called outside
13765        // of a locked context there is intrinsically a race with
13766        // the value the caller will receive and someone else changing it.
13767        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13768        // we will switch to the calling user if access to the current user fails.
13769        int targetUserId = unsafeConvertIncomingUser(userId);
13770
13771        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13772            final boolean allow;
13773            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13774                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13775                // If the caller has this permission, they always pass go.  And collect $200.
13776                allow = true;
13777            } else if (allowMode == ALLOW_FULL_ONLY) {
13778                // We require full access, sucks to be you.
13779                allow = false;
13780            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13781                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13782                // If the caller does not have either permission, they are always doomed.
13783                allow = false;
13784            } else if (allowMode == ALLOW_NON_FULL) {
13785                // We are blanket allowing non-full access, you lucky caller!
13786                allow = true;
13787            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13788                // We may or may not allow this depending on whether the two users are
13789                // in the same profile.
13790                synchronized (mUserProfileGroupIdsSelfLocked) {
13791                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13792                            UserInfo.NO_PROFILE_GROUP_ID);
13793                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13794                            UserInfo.NO_PROFILE_GROUP_ID);
13795                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13796                            && callingProfile == targetProfile;
13797                }
13798            } else {
13799                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13800            }
13801            if (!allow) {
13802                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13803                    // In this case, they would like to just execute as their
13804                    // owner user instead of failing.
13805                    targetUserId = callingUserId;
13806                } else {
13807                    StringBuilder builder = new StringBuilder(128);
13808                    builder.append("Permission Denial: ");
13809                    builder.append(name);
13810                    if (callerPackage != null) {
13811                        builder.append(" from ");
13812                        builder.append(callerPackage);
13813                    }
13814                    builder.append(" asks to run as user ");
13815                    builder.append(userId);
13816                    builder.append(" but is calling from user ");
13817                    builder.append(UserHandle.getUserId(callingUid));
13818                    builder.append("; this requires ");
13819                    builder.append(INTERACT_ACROSS_USERS_FULL);
13820                    if (allowMode != ALLOW_FULL_ONLY) {
13821                        builder.append(" or ");
13822                        builder.append(INTERACT_ACROSS_USERS);
13823                    }
13824                    String msg = builder.toString();
13825                    Slog.w(TAG, msg);
13826                    throw new SecurityException(msg);
13827                }
13828            }
13829        }
13830        if (!allowAll && targetUserId < 0) {
13831            throw new IllegalArgumentException(
13832                    "Call does not support special user #" + targetUserId);
13833        }
13834        return targetUserId;
13835    }
13836
13837    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13838            String className, int flags) {
13839        boolean result = false;
13840        // For apps that don't have pre-defined UIDs, check for permission
13841        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13842            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13843                if (ActivityManager.checkUidPermission(
13844                        INTERACT_ACROSS_USERS,
13845                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13846                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13847                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13848                            + " requests FLAG_SINGLE_USER, but app does not hold "
13849                            + INTERACT_ACROSS_USERS;
13850                    Slog.w(TAG, msg);
13851                    throw new SecurityException(msg);
13852                }
13853                // Permission passed
13854                result = true;
13855            }
13856        } else if ("system".equals(componentProcessName)) {
13857            result = true;
13858        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
13859                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13860            // Phone app is allowed to export singleuser providers.
13861            result = true;
13862        } else {
13863            // App with pre-defined UID, check if it's a persistent app
13864            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13865        }
13866        if (DEBUG_MU) {
13867            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13868                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13869        }
13870        return result;
13871    }
13872
13873    /**
13874     * Checks to see if the caller is in the same app as the singleton
13875     * component, or the component is in a special app. It allows special apps
13876     * to export singleton components but prevents exporting singleton
13877     * components for regular apps.
13878     */
13879    boolean isValidSingletonCall(int callingUid, int componentUid) {
13880        int componentAppId = UserHandle.getAppId(componentUid);
13881        return UserHandle.isSameApp(callingUid, componentUid)
13882                || componentAppId == Process.SYSTEM_UID
13883                || componentAppId == Process.PHONE_UID
13884                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13885                        == PackageManager.PERMISSION_GRANTED;
13886    }
13887
13888    public int bindService(IApplicationThread caller, IBinder token,
13889            Intent service, String resolvedType,
13890            IServiceConnection connection, int flags, int userId) {
13891        enforceNotIsolatedCaller("bindService");
13892        // Refuse possible leaked file descriptors
13893        if (service != null && service.hasFileDescriptors() == true) {
13894            throw new IllegalArgumentException("File descriptors passed in Intent");
13895        }
13896
13897        synchronized(this) {
13898            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13899                    connection, flags, userId);
13900        }
13901    }
13902
13903    public boolean unbindService(IServiceConnection connection) {
13904        synchronized (this) {
13905            return mServices.unbindServiceLocked(connection);
13906        }
13907    }
13908
13909    public void publishService(IBinder token, Intent intent, IBinder service) {
13910        // Refuse possible leaked file descriptors
13911        if (intent != null && intent.hasFileDescriptors() == true) {
13912            throw new IllegalArgumentException("File descriptors passed in Intent");
13913        }
13914
13915        synchronized(this) {
13916            if (!(token instanceof ServiceRecord)) {
13917                throw new IllegalArgumentException("Invalid service token");
13918            }
13919            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13920        }
13921    }
13922
13923    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13924        // Refuse possible leaked file descriptors
13925        if (intent != null && intent.hasFileDescriptors() == true) {
13926            throw new IllegalArgumentException("File descriptors passed in Intent");
13927        }
13928
13929        synchronized(this) {
13930            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13931        }
13932    }
13933
13934    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13935        synchronized(this) {
13936            if (!(token instanceof ServiceRecord)) {
13937                throw new IllegalArgumentException("Invalid service token");
13938            }
13939            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13940        }
13941    }
13942
13943    // =========================================================
13944    // BACKUP AND RESTORE
13945    // =========================================================
13946
13947    // Cause the target app to be launched if necessary and its backup agent
13948    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13949    // activity manager to announce its creation.
13950    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13951        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13952        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13953
13954        synchronized(this) {
13955            // !!! TODO: currently no check here that we're already bound
13956            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13957            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13958            synchronized (stats) {
13959                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13960            }
13961
13962            // Backup agent is now in use, its package can't be stopped.
13963            try {
13964                AppGlobals.getPackageManager().setPackageStoppedState(
13965                        app.packageName, false, UserHandle.getUserId(app.uid));
13966            } catch (RemoteException e) {
13967            } catch (IllegalArgumentException e) {
13968                Slog.w(TAG, "Failed trying to unstop package "
13969                        + app.packageName + ": " + e);
13970            }
13971
13972            BackupRecord r = new BackupRecord(ss, app, backupMode);
13973            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13974                    ? new ComponentName(app.packageName, app.backupAgentName)
13975                    : new ComponentName("android", "FullBackupAgent");
13976            // startProcessLocked() returns existing proc's record if it's already running
13977            ProcessRecord proc = startProcessLocked(app.processName, app,
13978                    false, 0, "backup", hostingName, false, false, false);
13979            if (proc == null) {
13980                Slog.e(TAG, "Unable to start backup agent process " + r);
13981                return false;
13982            }
13983
13984            r.app = proc;
13985            mBackupTarget = r;
13986            mBackupAppName = app.packageName;
13987
13988            // Try not to kill the process during backup
13989            updateOomAdjLocked(proc);
13990
13991            // If the process is already attached, schedule the creation of the backup agent now.
13992            // If it is not yet live, this will be done when it attaches to the framework.
13993            if (proc.thread != null) {
13994                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13995                try {
13996                    proc.thread.scheduleCreateBackupAgent(app,
13997                            compatibilityInfoForPackageLocked(app), backupMode);
13998                } catch (RemoteException e) {
13999                    // Will time out on the backup manager side
14000                }
14001            } else {
14002                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14003            }
14004            // Invariants: at this point, the target app process exists and the application
14005            // is either already running or in the process of coming up.  mBackupTarget and
14006            // mBackupAppName describe the app, so that when it binds back to the AM we
14007            // know that it's scheduled for a backup-agent operation.
14008        }
14009
14010        return true;
14011    }
14012
14013    @Override
14014    public void clearPendingBackup() {
14015        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14016        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14017
14018        synchronized (this) {
14019            mBackupTarget = null;
14020            mBackupAppName = null;
14021        }
14022    }
14023
14024    // A backup agent has just come up
14025    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14026        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14027                + " = " + agent);
14028
14029        synchronized(this) {
14030            if (!agentPackageName.equals(mBackupAppName)) {
14031                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14032                return;
14033            }
14034        }
14035
14036        long oldIdent = Binder.clearCallingIdentity();
14037        try {
14038            IBackupManager bm = IBackupManager.Stub.asInterface(
14039                    ServiceManager.getService(Context.BACKUP_SERVICE));
14040            bm.agentConnected(agentPackageName, agent);
14041        } catch (RemoteException e) {
14042            // can't happen; the backup manager service is local
14043        } catch (Exception e) {
14044            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14045            e.printStackTrace();
14046        } finally {
14047            Binder.restoreCallingIdentity(oldIdent);
14048        }
14049    }
14050
14051    // done with this agent
14052    public void unbindBackupAgent(ApplicationInfo appInfo) {
14053        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14054        if (appInfo == null) {
14055            Slog.w(TAG, "unbind backup agent for null app");
14056            return;
14057        }
14058
14059        synchronized(this) {
14060            try {
14061                if (mBackupAppName == null) {
14062                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14063                    return;
14064                }
14065
14066                if (!mBackupAppName.equals(appInfo.packageName)) {
14067                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14068                    return;
14069                }
14070
14071                // Not backing this app up any more; reset its OOM adjustment
14072                final ProcessRecord proc = mBackupTarget.app;
14073                updateOomAdjLocked(proc);
14074
14075                // If the app crashed during backup, 'thread' will be null here
14076                if (proc.thread != null) {
14077                    try {
14078                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14079                                compatibilityInfoForPackageLocked(appInfo));
14080                    } catch (Exception e) {
14081                        Slog.e(TAG, "Exception when unbinding backup agent:");
14082                        e.printStackTrace();
14083                    }
14084                }
14085            } finally {
14086                mBackupTarget = null;
14087                mBackupAppName = null;
14088            }
14089        }
14090    }
14091    // =========================================================
14092    // BROADCASTS
14093    // =========================================================
14094
14095    private final List getStickiesLocked(String action, IntentFilter filter,
14096            List cur, int userId) {
14097        final ContentResolver resolver = mContext.getContentResolver();
14098        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14099        if (stickies == null) {
14100            return cur;
14101        }
14102        final ArrayList<Intent> list = stickies.get(action);
14103        if (list == null) {
14104            return cur;
14105        }
14106        int N = list.size();
14107        for (int i=0; i<N; i++) {
14108            Intent intent = list.get(i);
14109            if (filter.match(resolver, intent, true, TAG) >= 0) {
14110                if (cur == null) {
14111                    cur = new ArrayList<Intent>();
14112                }
14113                cur.add(intent);
14114            }
14115        }
14116        return cur;
14117    }
14118
14119    boolean isPendingBroadcastProcessLocked(int pid) {
14120        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14121                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14122    }
14123
14124    void skipPendingBroadcastLocked(int pid) {
14125            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14126            for (BroadcastQueue queue : mBroadcastQueues) {
14127                queue.skipPendingBroadcastLocked(pid);
14128            }
14129    }
14130
14131    // The app just attached; send any pending broadcasts that it should receive
14132    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14133        boolean didSomething = false;
14134        for (BroadcastQueue queue : mBroadcastQueues) {
14135            didSomething |= queue.sendPendingBroadcastsLocked(app);
14136        }
14137        return didSomething;
14138    }
14139
14140    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14141            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14142        enforceNotIsolatedCaller("registerReceiver");
14143        int callingUid;
14144        int callingPid;
14145        synchronized(this) {
14146            ProcessRecord callerApp = null;
14147            if (caller != null) {
14148                callerApp = getRecordForAppLocked(caller);
14149                if (callerApp == null) {
14150                    throw new SecurityException(
14151                            "Unable to find app for caller " + caller
14152                            + " (pid=" + Binder.getCallingPid()
14153                            + ") when registering receiver " + receiver);
14154                }
14155                if (callerApp.info.uid != Process.SYSTEM_UID &&
14156                        !callerApp.pkgList.containsKey(callerPackage) &&
14157                        !"android".equals(callerPackage)) {
14158                    throw new SecurityException("Given caller package " + callerPackage
14159                            + " is not running in process " + callerApp);
14160                }
14161                callingUid = callerApp.info.uid;
14162                callingPid = callerApp.pid;
14163            } else {
14164                callerPackage = null;
14165                callingUid = Binder.getCallingUid();
14166                callingPid = Binder.getCallingPid();
14167            }
14168
14169            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14170                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14171
14172            List allSticky = null;
14173
14174            // Look for any matching sticky broadcasts...
14175            Iterator actions = filter.actionsIterator();
14176            if (actions != null) {
14177                while (actions.hasNext()) {
14178                    String action = (String)actions.next();
14179                    allSticky = getStickiesLocked(action, filter, allSticky,
14180                            UserHandle.USER_ALL);
14181                    allSticky = getStickiesLocked(action, filter, allSticky,
14182                            UserHandle.getUserId(callingUid));
14183                }
14184            } else {
14185                allSticky = getStickiesLocked(null, filter, allSticky,
14186                        UserHandle.USER_ALL);
14187                allSticky = getStickiesLocked(null, filter, allSticky,
14188                        UserHandle.getUserId(callingUid));
14189            }
14190
14191            // The first sticky in the list is returned directly back to
14192            // the client.
14193            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14194
14195            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14196                    + ": " + sticky);
14197
14198            if (receiver == null) {
14199                return sticky;
14200            }
14201
14202            ReceiverList rl
14203                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14204            if (rl == null) {
14205                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14206                        userId, receiver);
14207                if (rl.app != null) {
14208                    rl.app.receivers.add(rl);
14209                } else {
14210                    try {
14211                        receiver.asBinder().linkToDeath(rl, 0);
14212                    } catch (RemoteException e) {
14213                        return sticky;
14214                    }
14215                    rl.linkedToDeath = true;
14216                }
14217                mRegisteredReceivers.put(receiver.asBinder(), rl);
14218            } else if (rl.uid != callingUid) {
14219                throw new IllegalArgumentException(
14220                        "Receiver requested to register for uid " + callingUid
14221                        + " was previously registered for uid " + rl.uid);
14222            } else if (rl.pid != callingPid) {
14223                throw new IllegalArgumentException(
14224                        "Receiver requested to register for pid " + callingPid
14225                        + " was previously registered for pid " + rl.pid);
14226            } else if (rl.userId != userId) {
14227                throw new IllegalArgumentException(
14228                        "Receiver requested to register for user " + userId
14229                        + " was previously registered for user " + rl.userId);
14230            }
14231            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14232                    permission, callingUid, userId);
14233            rl.add(bf);
14234            if (!bf.debugCheck()) {
14235                Slog.w(TAG, "==> For Dynamic broadast");
14236            }
14237            mReceiverResolver.addFilter(bf);
14238
14239            // Enqueue broadcasts for all existing stickies that match
14240            // this filter.
14241            if (allSticky != null) {
14242                ArrayList receivers = new ArrayList();
14243                receivers.add(bf);
14244
14245                int N = allSticky.size();
14246                for (int i=0; i<N; i++) {
14247                    Intent intent = (Intent)allSticky.get(i);
14248                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14249                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14250                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14251                            null, null, false, true, true, -1);
14252                    queue.enqueueParallelBroadcastLocked(r);
14253                    queue.scheduleBroadcastsLocked();
14254                }
14255            }
14256
14257            return sticky;
14258        }
14259    }
14260
14261    public void unregisterReceiver(IIntentReceiver receiver) {
14262        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14263
14264        final long origId = Binder.clearCallingIdentity();
14265        try {
14266            boolean doTrim = false;
14267
14268            synchronized(this) {
14269                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14270                if (rl != null) {
14271                    if (rl.curBroadcast != null) {
14272                        BroadcastRecord r = rl.curBroadcast;
14273                        final boolean doNext = finishReceiverLocked(
14274                                receiver.asBinder(), r.resultCode, r.resultData,
14275                                r.resultExtras, r.resultAbort);
14276                        if (doNext) {
14277                            doTrim = true;
14278                            r.queue.processNextBroadcast(false);
14279                        }
14280                    }
14281
14282                    if (rl.app != null) {
14283                        rl.app.receivers.remove(rl);
14284                    }
14285                    removeReceiverLocked(rl);
14286                    if (rl.linkedToDeath) {
14287                        rl.linkedToDeath = false;
14288                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14289                    }
14290                }
14291            }
14292
14293            // If we actually concluded any broadcasts, we might now be able
14294            // to trim the recipients' apps from our working set
14295            if (doTrim) {
14296                trimApplications();
14297                return;
14298            }
14299
14300        } finally {
14301            Binder.restoreCallingIdentity(origId);
14302        }
14303    }
14304
14305    void removeReceiverLocked(ReceiverList rl) {
14306        mRegisteredReceivers.remove(rl.receiver.asBinder());
14307        int N = rl.size();
14308        for (int i=0; i<N; i++) {
14309            mReceiverResolver.removeFilter(rl.get(i));
14310        }
14311    }
14312
14313    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14314        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14315            ProcessRecord r = mLruProcesses.get(i);
14316            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14317                try {
14318                    r.thread.dispatchPackageBroadcast(cmd, packages);
14319                } catch (RemoteException ex) {
14320                }
14321            }
14322        }
14323    }
14324
14325    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14326            int[] users) {
14327        List<ResolveInfo> receivers = null;
14328        try {
14329            HashSet<ComponentName> singleUserReceivers = null;
14330            boolean scannedFirstReceivers = false;
14331            for (int user : users) {
14332                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14333                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14334                if (user != 0 && newReceivers != null) {
14335                    // If this is not the primary user, we need to check for
14336                    // any receivers that should be filtered out.
14337                    for (int i=0; i<newReceivers.size(); i++) {
14338                        ResolveInfo ri = newReceivers.get(i);
14339                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14340                            newReceivers.remove(i);
14341                            i--;
14342                        }
14343                    }
14344                }
14345                if (newReceivers != null && newReceivers.size() == 0) {
14346                    newReceivers = null;
14347                }
14348                if (receivers == null) {
14349                    receivers = newReceivers;
14350                } else if (newReceivers != null) {
14351                    // We need to concatenate the additional receivers
14352                    // found with what we have do far.  This would be easy,
14353                    // but we also need to de-dup any receivers that are
14354                    // singleUser.
14355                    if (!scannedFirstReceivers) {
14356                        // Collect any single user receivers we had already retrieved.
14357                        scannedFirstReceivers = true;
14358                        for (int i=0; i<receivers.size(); i++) {
14359                            ResolveInfo ri = receivers.get(i);
14360                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14361                                ComponentName cn = new ComponentName(
14362                                        ri.activityInfo.packageName, ri.activityInfo.name);
14363                                if (singleUserReceivers == null) {
14364                                    singleUserReceivers = new HashSet<ComponentName>();
14365                                }
14366                                singleUserReceivers.add(cn);
14367                            }
14368                        }
14369                    }
14370                    // Add the new results to the existing results, tracking
14371                    // and de-dupping single user receivers.
14372                    for (int i=0; i<newReceivers.size(); i++) {
14373                        ResolveInfo ri = newReceivers.get(i);
14374                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14375                            ComponentName cn = new ComponentName(
14376                                    ri.activityInfo.packageName, ri.activityInfo.name);
14377                            if (singleUserReceivers == null) {
14378                                singleUserReceivers = new HashSet<ComponentName>();
14379                            }
14380                            if (!singleUserReceivers.contains(cn)) {
14381                                singleUserReceivers.add(cn);
14382                                receivers.add(ri);
14383                            }
14384                        } else {
14385                            receivers.add(ri);
14386                        }
14387                    }
14388                }
14389            }
14390        } catch (RemoteException ex) {
14391            // pm is in same process, this will never happen.
14392        }
14393        return receivers;
14394    }
14395
14396    private final int broadcastIntentLocked(ProcessRecord callerApp,
14397            String callerPackage, Intent intent, String resolvedType,
14398            IIntentReceiver resultTo, int resultCode, String resultData,
14399            Bundle map, String requiredPermission, int appOp,
14400            boolean ordered, boolean sticky, int callingPid, int callingUid,
14401            int userId) {
14402        intent = new Intent(intent);
14403
14404        // By default broadcasts do not go to stopped apps.
14405        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14406
14407        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14408            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14409            + " ordered=" + ordered + " userid=" + userId);
14410        if ((resultTo != null) && !ordered) {
14411            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14412        }
14413
14414        userId = handleIncomingUser(callingPid, callingUid, userId,
14415                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14416
14417        // Make sure that the user who is receiving this broadcast is started.
14418        // If not, we will just skip it.
14419
14420
14421        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14422            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14423                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14424                Slog.w(TAG, "Skipping broadcast of " + intent
14425                        + ": user " + userId + " is stopped");
14426                return ActivityManager.BROADCAST_SUCCESS;
14427            }
14428        }
14429
14430        /*
14431         * Prevent non-system code (defined here to be non-persistent
14432         * processes) from sending protected broadcasts.
14433         */
14434        int callingAppId = UserHandle.getAppId(callingUid);
14435        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14436            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14437            || callingAppId == Process.NFC_UID || callingUid == 0) {
14438            // Always okay.
14439        } else if (callerApp == null || !callerApp.persistent) {
14440            try {
14441                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14442                        intent.getAction())) {
14443                    String msg = "Permission Denial: not allowed to send broadcast "
14444                            + intent.getAction() + " from pid="
14445                            + callingPid + ", uid=" + callingUid;
14446                    Slog.w(TAG, msg);
14447                    throw new SecurityException(msg);
14448                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14449                    // Special case for compatibility: we don't want apps to send this,
14450                    // but historically it has not been protected and apps may be using it
14451                    // to poke their own app widget.  So, instead of making it protected,
14452                    // just limit it to the caller.
14453                    if (callerApp == null) {
14454                        String msg = "Permission Denial: not allowed to send broadcast "
14455                                + intent.getAction() + " from unknown caller.";
14456                        Slog.w(TAG, msg);
14457                        throw new SecurityException(msg);
14458                    } else if (intent.getComponent() != null) {
14459                        // They are good enough to send to an explicit component...  verify
14460                        // it is being sent to the calling app.
14461                        if (!intent.getComponent().getPackageName().equals(
14462                                callerApp.info.packageName)) {
14463                            String msg = "Permission Denial: not allowed to send broadcast "
14464                                    + intent.getAction() + " to "
14465                                    + intent.getComponent().getPackageName() + " from "
14466                                    + callerApp.info.packageName;
14467                            Slog.w(TAG, msg);
14468                            throw new SecurityException(msg);
14469                        }
14470                    } else {
14471                        // Limit broadcast to their own package.
14472                        intent.setPackage(callerApp.info.packageName);
14473                    }
14474                }
14475            } catch (RemoteException e) {
14476                Slog.w(TAG, "Remote exception", e);
14477                return ActivityManager.BROADCAST_SUCCESS;
14478            }
14479        }
14480
14481        // Handle special intents: if this broadcast is from the package
14482        // manager about a package being removed, we need to remove all of
14483        // its activities from the history stack.
14484        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14485                intent.getAction());
14486        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14487                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14488                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14489                || uidRemoved) {
14490            if (checkComponentPermission(
14491                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14492                    callingPid, callingUid, -1, true)
14493                    == PackageManager.PERMISSION_GRANTED) {
14494                if (uidRemoved) {
14495                    final Bundle intentExtras = intent.getExtras();
14496                    final int uid = intentExtras != null
14497                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14498                    if (uid >= 0) {
14499                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14500                        synchronized (bs) {
14501                            bs.removeUidStatsLocked(uid);
14502                        }
14503                        mAppOpsService.uidRemoved(uid);
14504                    }
14505                } else {
14506                    // If resources are unavailable just force stop all
14507                    // those packages and flush the attribute cache as well.
14508                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14509                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14510                        if (list != null && (list.length > 0)) {
14511                            for (String pkg : list) {
14512                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14513                                        "storage unmount");
14514                            }
14515                            sendPackageBroadcastLocked(
14516                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14517                        }
14518                    } else {
14519                        Uri data = intent.getData();
14520                        String ssp;
14521                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14522                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14523                                    intent.getAction());
14524                            boolean fullUninstall = removed &&
14525                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14526                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14527                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14528                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14529                                        false, fullUninstall, userId,
14530                                        removed ? "pkg removed" : "pkg changed");
14531                            }
14532                            if (removed) {
14533                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14534                                        new String[] {ssp}, userId);
14535                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14536                                    mAppOpsService.packageRemoved(
14537                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14538
14539                                    // Remove all permissions granted from/to this package
14540                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14541                                }
14542                            }
14543                        }
14544                    }
14545                }
14546            } else {
14547                String msg = "Permission Denial: " + intent.getAction()
14548                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14549                        + ", uid=" + callingUid + ")"
14550                        + " requires "
14551                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14552                Slog.w(TAG, msg);
14553                throw new SecurityException(msg);
14554            }
14555
14556        // Special case for adding a package: by default turn on compatibility
14557        // mode.
14558        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14559            Uri data = intent.getData();
14560            String ssp;
14561            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14562                mCompatModePackages.handlePackageAddedLocked(ssp,
14563                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14564            }
14565        }
14566
14567        /*
14568         * If this is the time zone changed action, queue up a message that will reset the timezone
14569         * of all currently running processes. This message will get queued up before the broadcast
14570         * happens.
14571         */
14572        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14573            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14574        }
14575
14576        /*
14577         * If the user set the time, let all running processes know.
14578         */
14579        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14580            final int is24Hour = intent.getBooleanExtra(
14581                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14582            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14583        }
14584
14585        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14586            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14587        }
14588
14589        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14590            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14591            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14592        }
14593
14594        // Add to the sticky list if requested.
14595        if (sticky) {
14596            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14597                    callingPid, callingUid)
14598                    != PackageManager.PERMISSION_GRANTED) {
14599                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14600                        + callingPid + ", uid=" + callingUid
14601                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14602                Slog.w(TAG, msg);
14603                throw new SecurityException(msg);
14604            }
14605            if (requiredPermission != null) {
14606                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14607                        + " and enforce permission " + requiredPermission);
14608                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14609            }
14610            if (intent.getComponent() != null) {
14611                throw new SecurityException(
14612                        "Sticky broadcasts can't target a specific component");
14613            }
14614            // We use userId directly here, since the "all" target is maintained
14615            // as a separate set of sticky broadcasts.
14616            if (userId != UserHandle.USER_ALL) {
14617                // But first, if this is not a broadcast to all users, then
14618                // make sure it doesn't conflict with an existing broadcast to
14619                // all users.
14620                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14621                        UserHandle.USER_ALL);
14622                if (stickies != null) {
14623                    ArrayList<Intent> list = stickies.get(intent.getAction());
14624                    if (list != null) {
14625                        int N = list.size();
14626                        int i;
14627                        for (i=0; i<N; i++) {
14628                            if (intent.filterEquals(list.get(i))) {
14629                                throw new IllegalArgumentException(
14630                                        "Sticky broadcast " + intent + " for user "
14631                                        + userId + " conflicts with existing global broadcast");
14632                            }
14633                        }
14634                    }
14635                }
14636            }
14637            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14638            if (stickies == null) {
14639                stickies = new ArrayMap<String, ArrayList<Intent>>();
14640                mStickyBroadcasts.put(userId, stickies);
14641            }
14642            ArrayList<Intent> list = stickies.get(intent.getAction());
14643            if (list == null) {
14644                list = new ArrayList<Intent>();
14645                stickies.put(intent.getAction(), list);
14646            }
14647            int N = list.size();
14648            int i;
14649            for (i=0; i<N; i++) {
14650                if (intent.filterEquals(list.get(i))) {
14651                    // This sticky already exists, replace it.
14652                    list.set(i, new Intent(intent));
14653                    break;
14654                }
14655            }
14656            if (i >= N) {
14657                list.add(new Intent(intent));
14658            }
14659        }
14660
14661        int[] users;
14662        if (userId == UserHandle.USER_ALL) {
14663            // Caller wants broadcast to go to all started users.
14664            users = mStartedUserArray;
14665        } else {
14666            // Caller wants broadcast to go to one specific user.
14667            users = new int[] {userId};
14668        }
14669
14670        // Figure out who all will receive this broadcast.
14671        List receivers = null;
14672        List<BroadcastFilter> registeredReceivers = null;
14673        // Need to resolve the intent to interested receivers...
14674        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14675                 == 0) {
14676            receivers = collectReceiverComponents(intent, resolvedType, users);
14677        }
14678        if (intent.getComponent() == null) {
14679            registeredReceivers = mReceiverResolver.queryIntent(intent,
14680                    resolvedType, false, userId);
14681        }
14682
14683        final boolean replacePending =
14684                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14685
14686        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14687                + " replacePending=" + replacePending);
14688
14689        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14690        if (!ordered && NR > 0) {
14691            // If we are not serializing this broadcast, then send the
14692            // registered receivers separately so they don't wait for the
14693            // components to be launched.
14694            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14695            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14696                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14697                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14698                    ordered, sticky, false, userId);
14699            if (DEBUG_BROADCAST) Slog.v(
14700                    TAG, "Enqueueing parallel broadcast " + r);
14701            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14702            if (!replaced) {
14703                queue.enqueueParallelBroadcastLocked(r);
14704                queue.scheduleBroadcastsLocked();
14705            }
14706            registeredReceivers = null;
14707            NR = 0;
14708        }
14709
14710        // Merge into one list.
14711        int ir = 0;
14712        if (receivers != null) {
14713            // A special case for PACKAGE_ADDED: do not allow the package
14714            // being added to see this broadcast.  This prevents them from
14715            // using this as a back door to get run as soon as they are
14716            // installed.  Maybe in the future we want to have a special install
14717            // broadcast or such for apps, but we'd like to deliberately make
14718            // this decision.
14719            String skipPackages[] = null;
14720            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14721                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14722                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14723                Uri data = intent.getData();
14724                if (data != null) {
14725                    String pkgName = data.getSchemeSpecificPart();
14726                    if (pkgName != null) {
14727                        skipPackages = new String[] { pkgName };
14728                    }
14729                }
14730            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14731                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14732            }
14733            if (skipPackages != null && (skipPackages.length > 0)) {
14734                for (String skipPackage : skipPackages) {
14735                    if (skipPackage != null) {
14736                        int NT = receivers.size();
14737                        for (int it=0; it<NT; it++) {
14738                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14739                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14740                                receivers.remove(it);
14741                                it--;
14742                                NT--;
14743                            }
14744                        }
14745                    }
14746                }
14747            }
14748
14749            int NT = receivers != null ? receivers.size() : 0;
14750            int it = 0;
14751            ResolveInfo curt = null;
14752            BroadcastFilter curr = null;
14753            while (it < NT && ir < NR) {
14754                if (curt == null) {
14755                    curt = (ResolveInfo)receivers.get(it);
14756                }
14757                if (curr == null) {
14758                    curr = registeredReceivers.get(ir);
14759                }
14760                if (curr.getPriority() >= curt.priority) {
14761                    // Insert this broadcast record into the final list.
14762                    receivers.add(it, curr);
14763                    ir++;
14764                    curr = null;
14765                    it++;
14766                    NT++;
14767                } else {
14768                    // Skip to the next ResolveInfo in the final list.
14769                    it++;
14770                    curt = null;
14771                }
14772            }
14773        }
14774        while (ir < NR) {
14775            if (receivers == null) {
14776                receivers = new ArrayList();
14777            }
14778            receivers.add(registeredReceivers.get(ir));
14779            ir++;
14780        }
14781
14782        if ((receivers != null && receivers.size() > 0)
14783                || resultTo != null) {
14784            BroadcastQueue queue = broadcastQueueForIntent(intent);
14785            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14786                    callerPackage, callingPid, callingUid, resolvedType,
14787                    requiredPermission, appOp, receivers, resultTo, resultCode,
14788                    resultData, map, ordered, sticky, false, userId);
14789            if (DEBUG_BROADCAST) Slog.v(
14790                    TAG, "Enqueueing ordered broadcast " + r
14791                    + ": prev had " + queue.mOrderedBroadcasts.size());
14792            if (DEBUG_BROADCAST) {
14793                int seq = r.intent.getIntExtra("seq", -1);
14794                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14795            }
14796            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14797            if (!replaced) {
14798                queue.enqueueOrderedBroadcastLocked(r);
14799                queue.scheduleBroadcastsLocked();
14800            }
14801        }
14802
14803        return ActivityManager.BROADCAST_SUCCESS;
14804    }
14805
14806    final Intent verifyBroadcastLocked(Intent intent) {
14807        // Refuse possible leaked file descriptors
14808        if (intent != null && intent.hasFileDescriptors() == true) {
14809            throw new IllegalArgumentException("File descriptors passed in Intent");
14810        }
14811
14812        int flags = intent.getFlags();
14813
14814        if (!mProcessesReady) {
14815            // if the caller really truly claims to know what they're doing, go
14816            // ahead and allow the broadcast without launching any receivers
14817            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14818                intent = new Intent(intent);
14819                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14820            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14821                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14822                        + " before boot completion");
14823                throw new IllegalStateException("Cannot broadcast before boot completed");
14824            }
14825        }
14826
14827        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14828            throw new IllegalArgumentException(
14829                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14830        }
14831
14832        return intent;
14833    }
14834
14835    public final int broadcastIntent(IApplicationThread caller,
14836            Intent intent, String resolvedType, IIntentReceiver resultTo,
14837            int resultCode, String resultData, Bundle map,
14838            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14839        enforceNotIsolatedCaller("broadcastIntent");
14840        synchronized(this) {
14841            intent = verifyBroadcastLocked(intent);
14842
14843            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14844            final int callingPid = Binder.getCallingPid();
14845            final int callingUid = Binder.getCallingUid();
14846            final long origId = Binder.clearCallingIdentity();
14847            int res = broadcastIntentLocked(callerApp,
14848                    callerApp != null ? callerApp.info.packageName : null,
14849                    intent, resolvedType, resultTo,
14850                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14851                    callingPid, callingUid, userId);
14852            Binder.restoreCallingIdentity(origId);
14853            return res;
14854        }
14855    }
14856
14857    int broadcastIntentInPackage(String packageName, int uid,
14858            Intent intent, String resolvedType, IIntentReceiver resultTo,
14859            int resultCode, String resultData, Bundle map,
14860            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14861        synchronized(this) {
14862            intent = verifyBroadcastLocked(intent);
14863
14864            final long origId = Binder.clearCallingIdentity();
14865            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14866                    resultTo, resultCode, resultData, map, requiredPermission,
14867                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14868            Binder.restoreCallingIdentity(origId);
14869            return res;
14870        }
14871    }
14872
14873    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14874        // Refuse possible leaked file descriptors
14875        if (intent != null && intent.hasFileDescriptors() == true) {
14876            throw new IllegalArgumentException("File descriptors passed in Intent");
14877        }
14878
14879        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14880                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14881
14882        synchronized(this) {
14883            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14884                    != PackageManager.PERMISSION_GRANTED) {
14885                String msg = "Permission Denial: unbroadcastIntent() from pid="
14886                        + Binder.getCallingPid()
14887                        + ", uid=" + Binder.getCallingUid()
14888                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14889                Slog.w(TAG, msg);
14890                throw new SecurityException(msg);
14891            }
14892            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14893            if (stickies != null) {
14894                ArrayList<Intent> list = stickies.get(intent.getAction());
14895                if (list != null) {
14896                    int N = list.size();
14897                    int i;
14898                    for (i=0; i<N; i++) {
14899                        if (intent.filterEquals(list.get(i))) {
14900                            list.remove(i);
14901                            break;
14902                        }
14903                    }
14904                    if (list.size() <= 0) {
14905                        stickies.remove(intent.getAction());
14906                    }
14907                }
14908                if (stickies.size() <= 0) {
14909                    mStickyBroadcasts.remove(userId);
14910                }
14911            }
14912        }
14913    }
14914
14915    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14916            String resultData, Bundle resultExtras, boolean resultAbort) {
14917        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14918        if (r == null) {
14919            Slog.w(TAG, "finishReceiver called but not found on queue");
14920            return false;
14921        }
14922
14923        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14924    }
14925
14926    void backgroundServicesFinishedLocked(int userId) {
14927        for (BroadcastQueue queue : mBroadcastQueues) {
14928            queue.backgroundServicesFinishedLocked(userId);
14929        }
14930    }
14931
14932    public void finishReceiver(IBinder who, int resultCode, String resultData,
14933            Bundle resultExtras, boolean resultAbort) {
14934        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14935
14936        // Refuse possible leaked file descriptors
14937        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14938            throw new IllegalArgumentException("File descriptors passed in Bundle");
14939        }
14940
14941        final long origId = Binder.clearCallingIdentity();
14942        try {
14943            boolean doNext = false;
14944            BroadcastRecord r;
14945
14946            synchronized(this) {
14947                r = broadcastRecordForReceiverLocked(who);
14948                if (r != null) {
14949                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14950                        resultData, resultExtras, resultAbort, true);
14951                }
14952            }
14953
14954            if (doNext) {
14955                r.queue.processNextBroadcast(false);
14956            }
14957            trimApplications();
14958        } finally {
14959            Binder.restoreCallingIdentity(origId);
14960        }
14961    }
14962
14963    // =========================================================
14964    // INSTRUMENTATION
14965    // =========================================================
14966
14967    public boolean startInstrumentation(ComponentName className,
14968            String profileFile, int flags, Bundle arguments,
14969            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14970            int userId, String abiOverride) {
14971        enforceNotIsolatedCaller("startInstrumentation");
14972        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14973                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14974        // Refuse possible leaked file descriptors
14975        if (arguments != null && arguments.hasFileDescriptors()) {
14976            throw new IllegalArgumentException("File descriptors passed in Bundle");
14977        }
14978
14979        synchronized(this) {
14980            InstrumentationInfo ii = null;
14981            ApplicationInfo ai = null;
14982            try {
14983                ii = mContext.getPackageManager().getInstrumentationInfo(
14984                    className, STOCK_PM_FLAGS);
14985                ai = AppGlobals.getPackageManager().getApplicationInfo(
14986                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14987            } catch (PackageManager.NameNotFoundException e) {
14988            } catch (RemoteException e) {
14989            }
14990            if (ii == null) {
14991                reportStartInstrumentationFailure(watcher, className,
14992                        "Unable to find instrumentation info for: " + className);
14993                return false;
14994            }
14995            if (ai == null) {
14996                reportStartInstrumentationFailure(watcher, className,
14997                        "Unable to find instrumentation target package: " + ii.targetPackage);
14998                return false;
14999            }
15000
15001            int match = mContext.getPackageManager().checkSignatures(
15002                    ii.targetPackage, ii.packageName);
15003            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15004                String msg = "Permission Denial: starting instrumentation "
15005                        + className + " from pid="
15006                        + Binder.getCallingPid()
15007                        + ", uid=" + Binder.getCallingPid()
15008                        + " not allowed because package " + ii.packageName
15009                        + " does not have a signature matching the target "
15010                        + ii.targetPackage;
15011                reportStartInstrumentationFailure(watcher, className, msg);
15012                throw new SecurityException(msg);
15013            }
15014
15015            final long origId = Binder.clearCallingIdentity();
15016            // Instrumentation can kill and relaunch even persistent processes
15017            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15018                    "start instr");
15019            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15020            app.instrumentationClass = className;
15021            app.instrumentationInfo = ai;
15022            app.instrumentationProfileFile = profileFile;
15023            app.instrumentationArguments = arguments;
15024            app.instrumentationWatcher = watcher;
15025            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15026            app.instrumentationResultClass = className;
15027            Binder.restoreCallingIdentity(origId);
15028        }
15029
15030        return true;
15031    }
15032
15033    /**
15034     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15035     * error to the logs, but if somebody is watching, send the report there too.  This enables
15036     * the "am" command to report errors with more information.
15037     *
15038     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15039     * @param cn The component name of the instrumentation.
15040     * @param report The error report.
15041     */
15042    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15043            ComponentName cn, String report) {
15044        Slog.w(TAG, report);
15045        try {
15046            if (watcher != null) {
15047                Bundle results = new Bundle();
15048                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15049                results.putString("Error", report);
15050                watcher.instrumentationStatus(cn, -1, results);
15051            }
15052        } catch (RemoteException e) {
15053            Slog.w(TAG, e);
15054        }
15055    }
15056
15057    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15058        if (app.instrumentationWatcher != null) {
15059            try {
15060                // NOTE:  IInstrumentationWatcher *must* be oneway here
15061                app.instrumentationWatcher.instrumentationFinished(
15062                    app.instrumentationClass,
15063                    resultCode,
15064                    results);
15065            } catch (RemoteException e) {
15066            }
15067        }
15068        if (app.instrumentationUiAutomationConnection != null) {
15069            try {
15070                app.instrumentationUiAutomationConnection.shutdown();
15071            } catch (RemoteException re) {
15072                /* ignore */
15073            }
15074            // Only a UiAutomation can set this flag and now that
15075            // it is finished we make sure it is reset to its default.
15076            mUserIsMonkey = false;
15077        }
15078        app.instrumentationWatcher = null;
15079        app.instrumentationUiAutomationConnection = null;
15080        app.instrumentationClass = null;
15081        app.instrumentationInfo = null;
15082        app.instrumentationProfileFile = null;
15083        app.instrumentationArguments = null;
15084
15085        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15086                "finished inst");
15087    }
15088
15089    public void finishInstrumentation(IApplicationThread target,
15090            int resultCode, Bundle results) {
15091        int userId = UserHandle.getCallingUserId();
15092        // Refuse possible leaked file descriptors
15093        if (results != null && results.hasFileDescriptors()) {
15094            throw new IllegalArgumentException("File descriptors passed in Intent");
15095        }
15096
15097        synchronized(this) {
15098            ProcessRecord app = getRecordForAppLocked(target);
15099            if (app == null) {
15100                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15101                return;
15102            }
15103            final long origId = Binder.clearCallingIdentity();
15104            finishInstrumentationLocked(app, resultCode, results);
15105            Binder.restoreCallingIdentity(origId);
15106        }
15107    }
15108
15109    // =========================================================
15110    // CONFIGURATION
15111    // =========================================================
15112
15113    public ConfigurationInfo getDeviceConfigurationInfo() {
15114        ConfigurationInfo config = new ConfigurationInfo();
15115        synchronized (this) {
15116            config.reqTouchScreen = mConfiguration.touchscreen;
15117            config.reqKeyboardType = mConfiguration.keyboard;
15118            config.reqNavigation = mConfiguration.navigation;
15119            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15120                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15121                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15122            }
15123            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15124                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15125                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15126            }
15127            config.reqGlEsVersion = GL_ES_VERSION;
15128        }
15129        return config;
15130    }
15131
15132    ActivityStack getFocusedStack() {
15133        return mStackSupervisor.getFocusedStack();
15134    }
15135
15136    public Configuration getConfiguration() {
15137        Configuration ci;
15138        synchronized(this) {
15139            ci = new Configuration(mConfiguration);
15140        }
15141        return ci;
15142    }
15143
15144    public void updatePersistentConfiguration(Configuration values) {
15145        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15146                "updateConfiguration()");
15147        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15148                "updateConfiguration()");
15149        if (values == null) {
15150            throw new NullPointerException("Configuration must not be null");
15151        }
15152
15153        synchronized(this) {
15154            final long origId = Binder.clearCallingIdentity();
15155            updateConfigurationLocked(values, null, true, false);
15156            Binder.restoreCallingIdentity(origId);
15157        }
15158    }
15159
15160    public void updateConfiguration(Configuration values) {
15161        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15162                "updateConfiguration()");
15163
15164        synchronized(this) {
15165            if (values == null && mWindowManager != null) {
15166                // sentinel: fetch the current configuration from the window manager
15167                values = mWindowManager.computeNewConfiguration();
15168            }
15169
15170            if (mWindowManager != null) {
15171                mProcessList.applyDisplaySize(mWindowManager);
15172            }
15173
15174            final long origId = Binder.clearCallingIdentity();
15175            if (values != null) {
15176                Settings.System.clearConfiguration(values);
15177            }
15178            updateConfigurationLocked(values, null, false, false);
15179            Binder.restoreCallingIdentity(origId);
15180        }
15181    }
15182
15183    /**
15184     * Do either or both things: (1) change the current configuration, and (2)
15185     * make sure the given activity is running with the (now) current
15186     * configuration.  Returns true if the activity has been left running, or
15187     * false if <var>starting</var> is being destroyed to match the new
15188     * configuration.
15189     * @param persistent TODO
15190     */
15191    boolean updateConfigurationLocked(Configuration values,
15192            ActivityRecord starting, boolean persistent, boolean initLocale) {
15193        int changes = 0;
15194
15195        if (values != null) {
15196            Configuration newConfig = new Configuration(mConfiguration);
15197            changes = newConfig.updateFrom(values);
15198            if (changes != 0) {
15199                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15200                    Slog.i(TAG, "Updating configuration to: " + values);
15201                }
15202
15203                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15204
15205                if (values.locale != null && !initLocale) {
15206                    saveLocaleLocked(values.locale,
15207                                     !values.locale.equals(mConfiguration.locale),
15208                                     values.userSetLocale);
15209                }
15210
15211                mConfigurationSeq++;
15212                if (mConfigurationSeq <= 0) {
15213                    mConfigurationSeq = 1;
15214                }
15215                newConfig.seq = mConfigurationSeq;
15216                mConfiguration = newConfig;
15217                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15218                //mUsageStatsService.noteStartConfig(newConfig);
15219
15220                final Configuration configCopy = new Configuration(mConfiguration);
15221
15222                // TODO: If our config changes, should we auto dismiss any currently
15223                // showing dialogs?
15224                mShowDialogs = shouldShowDialogs(newConfig);
15225
15226                AttributeCache ac = AttributeCache.instance();
15227                if (ac != null) {
15228                    ac.updateConfiguration(configCopy);
15229                }
15230
15231                // Make sure all resources in our process are updated
15232                // right now, so that anyone who is going to retrieve
15233                // resource values after we return will be sure to get
15234                // the new ones.  This is especially important during
15235                // boot, where the first config change needs to guarantee
15236                // all resources have that config before following boot
15237                // code is executed.
15238                mSystemThread.applyConfigurationToResources(configCopy);
15239
15240                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15241                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15242                    msg.obj = new Configuration(configCopy);
15243                    mHandler.sendMessage(msg);
15244                }
15245
15246                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15247                    ProcessRecord app = mLruProcesses.get(i);
15248                    try {
15249                        if (app.thread != null) {
15250                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15251                                    + app.processName + " new config " + mConfiguration);
15252                            app.thread.scheduleConfigurationChanged(configCopy);
15253                        }
15254                    } catch (Exception e) {
15255                    }
15256                }
15257                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15258                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15259                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15260                        | Intent.FLAG_RECEIVER_FOREGROUND);
15261                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15262                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15263                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15264                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15265                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15266                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15267                    broadcastIntentLocked(null, null, intent,
15268                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15269                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15270                }
15271            }
15272        }
15273
15274        boolean kept = true;
15275        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15276        // mainStack is null during startup.
15277        if (mainStack != null) {
15278            if (changes != 0 && starting == null) {
15279                // If the configuration changed, and the caller is not already
15280                // in the process of starting an activity, then find the top
15281                // activity to check if its configuration needs to change.
15282                starting = mainStack.topRunningActivityLocked(null);
15283            }
15284
15285            if (starting != null) {
15286                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15287                // And we need to make sure at this point that all other activities
15288                // are made visible with the correct configuration.
15289                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15290            }
15291        }
15292
15293        if (values != null && mWindowManager != null) {
15294            mWindowManager.setNewConfiguration(mConfiguration);
15295        }
15296
15297        return kept;
15298    }
15299
15300    /**
15301     * Decide based on the configuration whether we should shouw the ANR,
15302     * crash, etc dialogs.  The idea is that if there is no affordnace to
15303     * press the on-screen buttons, we shouldn't show the dialog.
15304     *
15305     * A thought: SystemUI might also want to get told about this, the Power
15306     * dialog / global actions also might want different behaviors.
15307     */
15308    private static final boolean shouldShowDialogs(Configuration config) {
15309        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15310                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15311    }
15312
15313    /**
15314     * Save the locale.  You must be inside a synchronized (this) block.
15315     */
15316    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15317        if(isDiff) {
15318            SystemProperties.set("user.language", l.getLanguage());
15319            SystemProperties.set("user.region", l.getCountry());
15320        }
15321
15322        if(isPersist) {
15323            SystemProperties.set("persist.sys.language", l.getLanguage());
15324            SystemProperties.set("persist.sys.country", l.getCountry());
15325            SystemProperties.set("persist.sys.localevar", l.getVariant());
15326        }
15327    }
15328
15329    @Override
15330    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15331        ActivityRecord srec = ActivityRecord.forToken(token);
15332        return srec != null && srec.task.affinity != null &&
15333                srec.task.affinity.equals(destAffinity);
15334    }
15335
15336    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15337            Intent resultData) {
15338
15339        synchronized (this) {
15340            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15341            if (stack != null) {
15342                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15343            }
15344            return false;
15345        }
15346    }
15347
15348    public int getLaunchedFromUid(IBinder activityToken) {
15349        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15350        if (srec == null) {
15351            return -1;
15352        }
15353        return srec.launchedFromUid;
15354    }
15355
15356    public String getLaunchedFromPackage(IBinder activityToken) {
15357        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15358        if (srec == null) {
15359            return null;
15360        }
15361        return srec.launchedFromPackage;
15362    }
15363
15364    // =========================================================
15365    // LIFETIME MANAGEMENT
15366    // =========================================================
15367
15368    // Returns which broadcast queue the app is the current [or imminent] receiver
15369    // on, or 'null' if the app is not an active broadcast recipient.
15370    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15371        BroadcastRecord r = app.curReceiver;
15372        if (r != null) {
15373            return r.queue;
15374        }
15375
15376        // It's not the current receiver, but it might be starting up to become one
15377        synchronized (this) {
15378            for (BroadcastQueue queue : mBroadcastQueues) {
15379                r = queue.mPendingBroadcast;
15380                if (r != null && r.curApp == app) {
15381                    // found it; report which queue it's in
15382                    return queue;
15383                }
15384            }
15385        }
15386
15387        return null;
15388    }
15389
15390    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15391            boolean doingAll, long now) {
15392        if (mAdjSeq == app.adjSeq) {
15393            // This adjustment has already been computed.
15394            return app.curRawAdj;
15395        }
15396
15397        if (app.thread == null) {
15398            app.adjSeq = mAdjSeq;
15399            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15400            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15401            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15402        }
15403
15404        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15405        app.adjSource = null;
15406        app.adjTarget = null;
15407        app.empty = false;
15408        app.cached = false;
15409
15410        final int activitiesSize = app.activities.size();
15411
15412        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15413            // The max adjustment doesn't allow this app to be anything
15414            // below foreground, so it is not worth doing work for it.
15415            app.adjType = "fixed";
15416            app.adjSeq = mAdjSeq;
15417            app.curRawAdj = app.maxAdj;
15418            app.foregroundActivities = false;
15419            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15420            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15421            // System processes can do UI, and when they do we want to have
15422            // them trim their memory after the user leaves the UI.  To
15423            // facilitate this, here we need to determine whether or not it
15424            // is currently showing UI.
15425            app.systemNoUi = true;
15426            if (app == TOP_APP) {
15427                app.systemNoUi = false;
15428            } else if (activitiesSize > 0) {
15429                for (int j = 0; j < activitiesSize; j++) {
15430                    final ActivityRecord r = app.activities.get(j);
15431                    if (r.visible) {
15432                        app.systemNoUi = false;
15433                    }
15434                }
15435            }
15436            if (!app.systemNoUi) {
15437                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15438            }
15439            return (app.curAdj=app.maxAdj);
15440        }
15441
15442        app.systemNoUi = false;
15443
15444        // Determine the importance of the process, starting with most
15445        // important to least, and assign an appropriate OOM adjustment.
15446        int adj;
15447        int schedGroup;
15448        int procState;
15449        boolean foregroundActivities = false;
15450        BroadcastQueue queue;
15451        if (app == TOP_APP) {
15452            // The last app on the list is the foreground app.
15453            adj = ProcessList.FOREGROUND_APP_ADJ;
15454            schedGroup = Process.THREAD_GROUP_DEFAULT;
15455            app.adjType = "top-activity";
15456            foregroundActivities = true;
15457            procState = ActivityManager.PROCESS_STATE_TOP;
15458        } else if (app.instrumentationClass != null) {
15459            // Don't want to kill running instrumentation.
15460            adj = ProcessList.FOREGROUND_APP_ADJ;
15461            schedGroup = Process.THREAD_GROUP_DEFAULT;
15462            app.adjType = "instrumentation";
15463            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15464        } else if ((queue = isReceivingBroadcast(app)) != null) {
15465            // An app that is currently receiving a broadcast also
15466            // counts as being in the foreground for OOM killer purposes.
15467            // It's placed in a sched group based on the nature of the
15468            // broadcast as reflected by which queue it's active in.
15469            adj = ProcessList.FOREGROUND_APP_ADJ;
15470            schedGroup = (queue == mFgBroadcastQueue)
15471                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15472            app.adjType = "broadcast";
15473            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15474        } else if (app.executingServices.size() > 0) {
15475            // An app that is currently executing a service callback also
15476            // counts as being in the foreground.
15477            adj = ProcessList.FOREGROUND_APP_ADJ;
15478            schedGroup = app.execServicesFg ?
15479                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15480            app.adjType = "exec-service";
15481            procState = ActivityManager.PROCESS_STATE_SERVICE;
15482            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15483        } else {
15484            // As far as we know the process is empty.  We may change our mind later.
15485            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15486            // At this point we don't actually know the adjustment.  Use the cached adj
15487            // value that the caller wants us to.
15488            adj = cachedAdj;
15489            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15490            app.cached = true;
15491            app.empty = true;
15492            app.adjType = "cch-empty";
15493        }
15494
15495        // Examine all activities if not already foreground.
15496        if (!foregroundActivities && activitiesSize > 0) {
15497            for (int j = 0; j < activitiesSize; j++) {
15498                final ActivityRecord r = app.activities.get(j);
15499                if (r.app != app) {
15500                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15501                            + app + "?!?");
15502                    continue;
15503                }
15504                if (r.visible) {
15505                    // App has a visible activity; only upgrade adjustment.
15506                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15507                        adj = ProcessList.VISIBLE_APP_ADJ;
15508                        app.adjType = "visible";
15509                    }
15510                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15511                        procState = ActivityManager.PROCESS_STATE_TOP;
15512                    }
15513                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15514                    app.cached = false;
15515                    app.empty = false;
15516                    foregroundActivities = true;
15517                    break;
15518                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15519                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15520                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15521                        app.adjType = "pausing";
15522                    }
15523                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15524                        procState = ActivityManager.PROCESS_STATE_TOP;
15525                    }
15526                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15527                    app.cached = false;
15528                    app.empty = false;
15529                    foregroundActivities = true;
15530                } else if (r.state == ActivityState.STOPPING) {
15531                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15532                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15533                        app.adjType = "stopping";
15534                    }
15535                    // For the process state, we will at this point consider the
15536                    // process to be cached.  It will be cached either as an activity
15537                    // or empty depending on whether the activity is finishing.  We do
15538                    // this so that we can treat the process as cached for purposes of
15539                    // memory trimming (determing current memory level, trim command to
15540                    // send to process) since there can be an arbitrary number of stopping
15541                    // processes and they should soon all go into the cached state.
15542                    if (!r.finishing) {
15543                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15544                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15545                        }
15546                    }
15547                    app.cached = false;
15548                    app.empty = false;
15549                    foregroundActivities = true;
15550                } else {
15551                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15552                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15553                        app.adjType = "cch-act";
15554                    }
15555                }
15556            }
15557        }
15558
15559        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15560            if (app.foregroundServices) {
15561                // The user is aware of this app, so make it visible.
15562                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15563                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15564                app.cached = false;
15565                app.adjType = "fg-service";
15566                schedGroup = Process.THREAD_GROUP_DEFAULT;
15567            } else if (app.forcingToForeground != null) {
15568                // The user is aware of this app, so make it visible.
15569                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15570                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15571                app.cached = false;
15572                app.adjType = "force-fg";
15573                app.adjSource = app.forcingToForeground;
15574                schedGroup = Process.THREAD_GROUP_DEFAULT;
15575            }
15576        }
15577
15578        if (app == mHeavyWeightProcess) {
15579            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15580                // We don't want to kill the current heavy-weight process.
15581                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15582                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15583                app.cached = false;
15584                app.adjType = "heavy";
15585            }
15586            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15587                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15588            }
15589        }
15590
15591        if (app == mHomeProcess) {
15592            if (adj > ProcessList.HOME_APP_ADJ) {
15593                // This process is hosting what we currently consider to be the
15594                // home app, so we don't want to let it go into the background.
15595                adj = ProcessList.HOME_APP_ADJ;
15596                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15597                app.cached = false;
15598                app.adjType = "home";
15599            }
15600            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15601                procState = ActivityManager.PROCESS_STATE_HOME;
15602            }
15603        }
15604
15605        if (app == mPreviousProcess && app.activities.size() > 0) {
15606            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15607                // This was the previous process that showed UI to the user.
15608                // We want to try to keep it around more aggressively, to give
15609                // a good experience around switching between two apps.
15610                adj = ProcessList.PREVIOUS_APP_ADJ;
15611                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15612                app.cached = false;
15613                app.adjType = "previous";
15614            }
15615            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15616                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15617            }
15618        }
15619
15620        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15621                + " reason=" + app.adjType);
15622
15623        // By default, we use the computed adjustment.  It may be changed if
15624        // there are applications dependent on our services or providers, but
15625        // this gives us a baseline and makes sure we don't get into an
15626        // infinite recursion.
15627        app.adjSeq = mAdjSeq;
15628        app.curRawAdj = adj;
15629        app.hasStartedServices = false;
15630
15631        if (mBackupTarget != null && app == mBackupTarget.app) {
15632            // If possible we want to avoid killing apps while they're being backed up
15633            if (adj > ProcessList.BACKUP_APP_ADJ) {
15634                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15635                adj = ProcessList.BACKUP_APP_ADJ;
15636                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15637                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15638                }
15639                app.adjType = "backup";
15640                app.cached = false;
15641            }
15642            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15643                procState = ActivityManager.PROCESS_STATE_BACKUP;
15644            }
15645        }
15646
15647        boolean mayBeTop = false;
15648
15649        for (int is = app.services.size()-1;
15650                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15651                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15652                        || procState > ActivityManager.PROCESS_STATE_TOP);
15653                is--) {
15654            ServiceRecord s = app.services.valueAt(is);
15655            if (s.startRequested) {
15656                app.hasStartedServices = true;
15657                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15658                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15659                }
15660                if (app.hasShownUi && app != mHomeProcess) {
15661                    // If this process has shown some UI, let it immediately
15662                    // go to the LRU list because it may be pretty heavy with
15663                    // UI stuff.  We'll tag it with a label just to help
15664                    // debug and understand what is going on.
15665                    if (adj > ProcessList.SERVICE_ADJ) {
15666                        app.adjType = "cch-started-ui-services";
15667                    }
15668                } else {
15669                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15670                        // This service has seen some activity within
15671                        // recent memory, so we will keep its process ahead
15672                        // of the background processes.
15673                        if (adj > ProcessList.SERVICE_ADJ) {
15674                            adj = ProcessList.SERVICE_ADJ;
15675                            app.adjType = "started-services";
15676                            app.cached = false;
15677                        }
15678                    }
15679                    // If we have let the service slide into the background
15680                    // state, still have some text describing what it is doing
15681                    // even though the service no longer has an impact.
15682                    if (adj > ProcessList.SERVICE_ADJ) {
15683                        app.adjType = "cch-started-services";
15684                    }
15685                }
15686            }
15687            for (int conni = s.connections.size()-1;
15688                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15689                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15690                            || procState > ActivityManager.PROCESS_STATE_TOP);
15691                    conni--) {
15692                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15693                for (int i = 0;
15694                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15695                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15696                                || procState > ActivityManager.PROCESS_STATE_TOP);
15697                        i++) {
15698                    // XXX should compute this based on the max of
15699                    // all connected clients.
15700                    ConnectionRecord cr = clist.get(i);
15701                    if (cr.binding.client == app) {
15702                        // Binding to ourself is not interesting.
15703                        continue;
15704                    }
15705                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15706                        ProcessRecord client = cr.binding.client;
15707                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15708                                TOP_APP, doingAll, now);
15709                        int clientProcState = client.curProcState;
15710                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15711                            // If the other app is cached for any reason, for purposes here
15712                            // we are going to consider it empty.  The specific cached state
15713                            // doesn't propagate except under certain conditions.
15714                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15715                        }
15716                        String adjType = null;
15717                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15718                            // Not doing bind OOM management, so treat
15719                            // this guy more like a started service.
15720                            if (app.hasShownUi && app != mHomeProcess) {
15721                                // If this process has shown some UI, let it immediately
15722                                // go to the LRU list because it may be pretty heavy with
15723                                // UI stuff.  We'll tag it with a label just to help
15724                                // debug and understand what is going on.
15725                                if (adj > clientAdj) {
15726                                    adjType = "cch-bound-ui-services";
15727                                }
15728                                app.cached = false;
15729                                clientAdj = adj;
15730                                clientProcState = procState;
15731                            } else {
15732                                if (now >= (s.lastActivity
15733                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15734                                    // This service has not seen activity within
15735                                    // recent memory, so allow it to drop to the
15736                                    // LRU list if there is no other reason to keep
15737                                    // it around.  We'll also tag it with a label just
15738                                    // to help debug and undertand what is going on.
15739                                    if (adj > clientAdj) {
15740                                        adjType = "cch-bound-services";
15741                                    }
15742                                    clientAdj = adj;
15743                                }
15744                            }
15745                        }
15746                        if (adj > clientAdj) {
15747                            // If this process has recently shown UI, and
15748                            // the process that is binding to it is less
15749                            // important than being visible, then we don't
15750                            // care about the binding as much as we care
15751                            // about letting this process get into the LRU
15752                            // list to be killed and restarted if needed for
15753                            // memory.
15754                            if (app.hasShownUi && app != mHomeProcess
15755                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15756                                adjType = "cch-bound-ui-services";
15757                            } else {
15758                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15759                                        |Context.BIND_IMPORTANT)) != 0) {
15760                                    adj = clientAdj;
15761                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15762                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15763                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15764                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15765                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15766                                    adj = clientAdj;
15767                                } else {
15768                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15769                                        adj = ProcessList.VISIBLE_APP_ADJ;
15770                                    }
15771                                }
15772                                if (!client.cached) {
15773                                    app.cached = false;
15774                                }
15775                                adjType = "service";
15776                            }
15777                        }
15778                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15779                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15780                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15781                            }
15782                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15783                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15784                                    // Special handling of clients who are in the top state.
15785                                    // We *may* want to consider this process to be in the
15786                                    // top state as well, but only if there is not another
15787                                    // reason for it to be running.  Being on the top is a
15788                                    // special state, meaning you are specifically running
15789                                    // for the current top app.  If the process is already
15790                                    // running in the background for some other reason, it
15791                                    // is more important to continue considering it to be
15792                                    // in the background state.
15793                                    mayBeTop = true;
15794                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15795                                } else {
15796                                    // Special handling for above-top states (persistent
15797                                    // processes).  These should not bring the current process
15798                                    // into the top state, since they are not on top.  Instead
15799                                    // give them the best state after that.
15800                                    clientProcState =
15801                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15802                                }
15803                            }
15804                        } else {
15805                            if (clientProcState <
15806                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15807                                clientProcState =
15808                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15809                            }
15810                        }
15811                        if (procState > clientProcState) {
15812                            procState = clientProcState;
15813                        }
15814                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15815                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15816                            app.pendingUiClean = true;
15817                        }
15818                        if (adjType != null) {
15819                            app.adjType = adjType;
15820                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15821                                    .REASON_SERVICE_IN_USE;
15822                            app.adjSource = cr.binding.client;
15823                            app.adjSourceProcState = clientProcState;
15824                            app.adjTarget = s.name;
15825                        }
15826                    }
15827                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15828                        app.treatLikeActivity = true;
15829                    }
15830                    final ActivityRecord a = cr.activity;
15831                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15832                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15833                                (a.visible || a.state == ActivityState.RESUMED
15834                                 || a.state == ActivityState.PAUSING)) {
15835                            adj = ProcessList.FOREGROUND_APP_ADJ;
15836                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15837                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15838                            }
15839                            app.cached = false;
15840                            app.adjType = "service";
15841                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15842                                    .REASON_SERVICE_IN_USE;
15843                            app.adjSource = a;
15844                            app.adjSourceProcState = procState;
15845                            app.adjTarget = s.name;
15846                        }
15847                    }
15848                }
15849            }
15850        }
15851
15852        for (int provi = app.pubProviders.size()-1;
15853                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15854                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15855                        || procState > ActivityManager.PROCESS_STATE_TOP);
15856                provi--) {
15857            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15858            for (int i = cpr.connections.size()-1;
15859                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15860                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15861                            || procState > ActivityManager.PROCESS_STATE_TOP);
15862                    i--) {
15863                ContentProviderConnection conn = cpr.connections.get(i);
15864                ProcessRecord client = conn.client;
15865                if (client == app) {
15866                    // Being our own client is not interesting.
15867                    continue;
15868                }
15869                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15870                int clientProcState = client.curProcState;
15871                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15872                    // If the other app is cached for any reason, for purposes here
15873                    // we are going to consider it empty.
15874                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15875                }
15876                if (adj > clientAdj) {
15877                    if (app.hasShownUi && app != mHomeProcess
15878                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15879                        app.adjType = "cch-ui-provider";
15880                    } else {
15881                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15882                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15883                        app.adjType = "provider";
15884                    }
15885                    app.cached &= client.cached;
15886                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15887                            .REASON_PROVIDER_IN_USE;
15888                    app.adjSource = client;
15889                    app.adjSourceProcState = clientProcState;
15890                    app.adjTarget = cpr.name;
15891                }
15892                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15893                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15894                        // Special handling of clients who are in the top state.
15895                        // We *may* want to consider this process to be in the
15896                        // top state as well, but only if there is not another
15897                        // reason for it to be running.  Being on the top is a
15898                        // special state, meaning you are specifically running
15899                        // for the current top app.  If the process is already
15900                        // running in the background for some other reason, it
15901                        // is more important to continue considering it to be
15902                        // in the background state.
15903                        mayBeTop = true;
15904                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15905                    } else {
15906                        // Special handling for above-top states (persistent
15907                        // processes).  These should not bring the current process
15908                        // into the top state, since they are not on top.  Instead
15909                        // give them the best state after that.
15910                        clientProcState =
15911                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15912                    }
15913                }
15914                if (procState > clientProcState) {
15915                    procState = clientProcState;
15916                }
15917                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15918                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15919                }
15920            }
15921            // If the provider has external (non-framework) process
15922            // dependencies, ensure that its adjustment is at least
15923            // FOREGROUND_APP_ADJ.
15924            if (cpr.hasExternalProcessHandles()) {
15925                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15926                    adj = ProcessList.FOREGROUND_APP_ADJ;
15927                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15928                    app.cached = false;
15929                    app.adjType = "provider";
15930                    app.adjTarget = cpr.name;
15931                }
15932                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15933                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15934                }
15935            }
15936        }
15937
15938        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15939            // A client of one of our services or providers is in the top state.  We
15940            // *may* want to be in the top state, but not if we are already running in
15941            // the background for some other reason.  For the decision here, we are going
15942            // to pick out a few specific states that we want to remain in when a client
15943            // is top (states that tend to be longer-term) and otherwise allow it to go
15944            // to the top state.
15945            switch (procState) {
15946                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15947                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15948                case ActivityManager.PROCESS_STATE_SERVICE:
15949                    // These all are longer-term states, so pull them up to the top
15950                    // of the background states, but not all the way to the top state.
15951                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15952                    break;
15953                default:
15954                    // Otherwise, top is a better choice, so take it.
15955                    procState = ActivityManager.PROCESS_STATE_TOP;
15956                    break;
15957            }
15958        }
15959
15960        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15961            if (app.hasClientActivities) {
15962                // This is a cached process, but with client activities.  Mark it so.
15963                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15964                app.adjType = "cch-client-act";
15965            } else if (app.treatLikeActivity) {
15966                // This is a cached process, but somebody wants us to treat it like it has
15967                // an activity, okay!
15968                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15969                app.adjType = "cch-as-act";
15970            }
15971        }
15972
15973        if (adj == ProcessList.SERVICE_ADJ) {
15974            if (doingAll) {
15975                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15976                mNewNumServiceProcs++;
15977                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15978                if (!app.serviceb) {
15979                    // This service isn't far enough down on the LRU list to
15980                    // normally be a B service, but if we are low on RAM and it
15981                    // is large we want to force it down since we would prefer to
15982                    // keep launcher over it.
15983                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15984                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15985                        app.serviceHighRam = true;
15986                        app.serviceb = true;
15987                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15988                    } else {
15989                        mNewNumAServiceProcs++;
15990                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15991                    }
15992                } else {
15993                    app.serviceHighRam = false;
15994                }
15995            }
15996            if (app.serviceb) {
15997                adj = ProcessList.SERVICE_B_ADJ;
15998            }
15999        }
16000
16001        app.curRawAdj = adj;
16002
16003        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16004        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16005        if (adj > app.maxAdj) {
16006            adj = app.maxAdj;
16007            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16008                schedGroup = Process.THREAD_GROUP_DEFAULT;
16009            }
16010        }
16011
16012        // Do final modification to adj.  Everything we do between here and applying
16013        // the final setAdj must be done in this function, because we will also use
16014        // it when computing the final cached adj later.  Note that we don't need to
16015        // worry about this for max adj above, since max adj will always be used to
16016        // keep it out of the cached vaues.
16017        app.curAdj = app.modifyRawOomAdj(adj);
16018        app.curSchedGroup = schedGroup;
16019        app.curProcState = procState;
16020        app.foregroundActivities = foregroundActivities;
16021
16022        return app.curRawAdj;
16023    }
16024
16025    /**
16026     * Schedule PSS collection of a process.
16027     */
16028    void requestPssLocked(ProcessRecord proc, int procState) {
16029        if (mPendingPssProcesses.contains(proc)) {
16030            return;
16031        }
16032        if (mPendingPssProcesses.size() == 0) {
16033            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16034        }
16035        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16036        proc.pssProcState = procState;
16037        mPendingPssProcesses.add(proc);
16038    }
16039
16040    /**
16041     * Schedule PSS collection of all processes.
16042     */
16043    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16044        if (!always) {
16045            if (now < (mLastFullPssTime +
16046                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16047                return;
16048            }
16049        }
16050        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16051        mLastFullPssTime = now;
16052        mFullPssPending = true;
16053        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16054        mPendingPssProcesses.clear();
16055        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16056            ProcessRecord app = mLruProcesses.get(i);
16057            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16058                app.pssProcState = app.setProcState;
16059                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16060                        isSleeping(), now);
16061                mPendingPssProcesses.add(app);
16062            }
16063        }
16064        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16065    }
16066
16067    /**
16068     * Ask a given process to GC right now.
16069     */
16070    final void performAppGcLocked(ProcessRecord app) {
16071        try {
16072            app.lastRequestedGc = SystemClock.uptimeMillis();
16073            if (app.thread != null) {
16074                if (app.reportLowMemory) {
16075                    app.reportLowMemory = false;
16076                    app.thread.scheduleLowMemory();
16077                } else {
16078                    app.thread.processInBackground();
16079                }
16080            }
16081        } catch (Exception e) {
16082            // whatever.
16083        }
16084    }
16085
16086    /**
16087     * Returns true if things are idle enough to perform GCs.
16088     */
16089    private final boolean canGcNowLocked() {
16090        boolean processingBroadcasts = false;
16091        for (BroadcastQueue q : mBroadcastQueues) {
16092            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16093                processingBroadcasts = true;
16094            }
16095        }
16096        return !processingBroadcasts
16097                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16098    }
16099
16100    /**
16101     * Perform GCs on all processes that are waiting for it, but only
16102     * if things are idle.
16103     */
16104    final void performAppGcsLocked() {
16105        final int N = mProcessesToGc.size();
16106        if (N <= 0) {
16107            return;
16108        }
16109        if (canGcNowLocked()) {
16110            while (mProcessesToGc.size() > 0) {
16111                ProcessRecord proc = mProcessesToGc.remove(0);
16112                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16113                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16114                            <= SystemClock.uptimeMillis()) {
16115                        // To avoid spamming the system, we will GC processes one
16116                        // at a time, waiting a few seconds between each.
16117                        performAppGcLocked(proc);
16118                        scheduleAppGcsLocked();
16119                        return;
16120                    } else {
16121                        // It hasn't been long enough since we last GCed this
16122                        // process...  put it in the list to wait for its time.
16123                        addProcessToGcListLocked(proc);
16124                        break;
16125                    }
16126                }
16127            }
16128
16129            scheduleAppGcsLocked();
16130        }
16131    }
16132
16133    /**
16134     * If all looks good, perform GCs on all processes waiting for them.
16135     */
16136    final void performAppGcsIfAppropriateLocked() {
16137        if (canGcNowLocked()) {
16138            performAppGcsLocked();
16139            return;
16140        }
16141        // Still not idle, wait some more.
16142        scheduleAppGcsLocked();
16143    }
16144
16145    /**
16146     * Schedule the execution of all pending app GCs.
16147     */
16148    final void scheduleAppGcsLocked() {
16149        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16150
16151        if (mProcessesToGc.size() > 0) {
16152            // Schedule a GC for the time to the next process.
16153            ProcessRecord proc = mProcessesToGc.get(0);
16154            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16155
16156            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16157            long now = SystemClock.uptimeMillis();
16158            if (when < (now+GC_TIMEOUT)) {
16159                when = now + GC_TIMEOUT;
16160            }
16161            mHandler.sendMessageAtTime(msg, when);
16162        }
16163    }
16164
16165    /**
16166     * Add a process to the array of processes waiting to be GCed.  Keeps the
16167     * list in sorted order by the last GC time.  The process can't already be
16168     * on the list.
16169     */
16170    final void addProcessToGcListLocked(ProcessRecord proc) {
16171        boolean added = false;
16172        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16173            if (mProcessesToGc.get(i).lastRequestedGc <
16174                    proc.lastRequestedGc) {
16175                added = true;
16176                mProcessesToGc.add(i+1, proc);
16177                break;
16178            }
16179        }
16180        if (!added) {
16181            mProcessesToGc.add(0, proc);
16182        }
16183    }
16184
16185    /**
16186     * Set up to ask a process to GC itself.  This will either do it
16187     * immediately, or put it on the list of processes to gc the next
16188     * time things are idle.
16189     */
16190    final void scheduleAppGcLocked(ProcessRecord app) {
16191        long now = SystemClock.uptimeMillis();
16192        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16193            return;
16194        }
16195        if (!mProcessesToGc.contains(app)) {
16196            addProcessToGcListLocked(app);
16197            scheduleAppGcsLocked();
16198        }
16199    }
16200
16201    final void checkExcessivePowerUsageLocked(boolean doKills) {
16202        updateCpuStatsNow();
16203
16204        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16205        boolean doWakeKills = doKills;
16206        boolean doCpuKills = doKills;
16207        if (mLastPowerCheckRealtime == 0) {
16208            doWakeKills = false;
16209        }
16210        if (mLastPowerCheckUptime == 0) {
16211            doCpuKills = false;
16212        }
16213        if (stats.isScreenOn()) {
16214            doWakeKills = false;
16215        }
16216        final long curRealtime = SystemClock.elapsedRealtime();
16217        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16218        final long curUptime = SystemClock.uptimeMillis();
16219        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16220        mLastPowerCheckRealtime = curRealtime;
16221        mLastPowerCheckUptime = curUptime;
16222        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16223            doWakeKills = false;
16224        }
16225        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16226            doCpuKills = false;
16227        }
16228        int i = mLruProcesses.size();
16229        while (i > 0) {
16230            i--;
16231            ProcessRecord app = mLruProcesses.get(i);
16232            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16233                long wtime;
16234                synchronized (stats) {
16235                    wtime = stats.getProcessWakeTime(app.info.uid,
16236                            app.pid, curRealtime);
16237                }
16238                long wtimeUsed = wtime - app.lastWakeTime;
16239                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16240                if (DEBUG_POWER) {
16241                    StringBuilder sb = new StringBuilder(128);
16242                    sb.append("Wake for ");
16243                    app.toShortString(sb);
16244                    sb.append(": over ");
16245                    TimeUtils.formatDuration(realtimeSince, sb);
16246                    sb.append(" used ");
16247                    TimeUtils.formatDuration(wtimeUsed, sb);
16248                    sb.append(" (");
16249                    sb.append((wtimeUsed*100)/realtimeSince);
16250                    sb.append("%)");
16251                    Slog.i(TAG, sb.toString());
16252                    sb.setLength(0);
16253                    sb.append("CPU for ");
16254                    app.toShortString(sb);
16255                    sb.append(": over ");
16256                    TimeUtils.formatDuration(uptimeSince, sb);
16257                    sb.append(" used ");
16258                    TimeUtils.formatDuration(cputimeUsed, sb);
16259                    sb.append(" (");
16260                    sb.append((cputimeUsed*100)/uptimeSince);
16261                    sb.append("%)");
16262                    Slog.i(TAG, sb.toString());
16263                }
16264                // If a process has held a wake lock for more
16265                // than 50% of the time during this period,
16266                // that sounds bad.  Kill!
16267                if (doWakeKills && realtimeSince > 0
16268                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16269                    synchronized (stats) {
16270                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16271                                realtimeSince, wtimeUsed);
16272                    }
16273                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16274                            + " during " + realtimeSince);
16275                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16276                } else if (doCpuKills && uptimeSince > 0
16277                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16278                    synchronized (stats) {
16279                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16280                                uptimeSince, cputimeUsed);
16281                    }
16282                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16283                            + " during " + uptimeSince);
16284                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16285                } else {
16286                    app.lastWakeTime = wtime;
16287                    app.lastCpuTime = app.curCpuTime;
16288                }
16289            }
16290        }
16291    }
16292
16293    private final boolean applyOomAdjLocked(ProcessRecord app,
16294            ProcessRecord TOP_APP, boolean doingAll, long now) {
16295        boolean success = true;
16296
16297        if (app.curRawAdj != app.setRawAdj) {
16298            app.setRawAdj = app.curRawAdj;
16299        }
16300
16301        int changes = 0;
16302
16303        if (app.curAdj != app.setAdj) {
16304            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16305            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16306                TAG, "Set " + app.pid + " " + app.processName +
16307                " adj " + app.curAdj + ": " + app.adjType);
16308            app.setAdj = app.curAdj;
16309        }
16310
16311        if (app.setSchedGroup != app.curSchedGroup) {
16312            app.setSchedGroup = app.curSchedGroup;
16313            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16314                    "Setting process group of " + app.processName
16315                    + " to " + app.curSchedGroup);
16316            if (app.waitingToKill != null &&
16317                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16318                killUnneededProcessLocked(app, app.waitingToKill);
16319                success = false;
16320            } else {
16321                if (true) {
16322                    long oldId = Binder.clearCallingIdentity();
16323                    try {
16324                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16325                    } catch (Exception e) {
16326                        Slog.w(TAG, "Failed setting process group of " + app.pid
16327                                + " to " + app.curSchedGroup);
16328                        e.printStackTrace();
16329                    } finally {
16330                        Binder.restoreCallingIdentity(oldId);
16331                    }
16332                } else {
16333                    if (app.thread != null) {
16334                        try {
16335                            app.thread.setSchedulingGroup(app.curSchedGroup);
16336                        } catch (RemoteException e) {
16337                        }
16338                    }
16339                }
16340                Process.setSwappiness(app.pid,
16341                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16342            }
16343        }
16344        if (app.repForegroundActivities != app.foregroundActivities) {
16345            app.repForegroundActivities = app.foregroundActivities;
16346            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16347        }
16348        if (app.repProcState != app.curProcState) {
16349            app.repProcState = app.curProcState;
16350            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16351            if (app.thread != null) {
16352                try {
16353                    if (false) {
16354                        //RuntimeException h = new RuntimeException("here");
16355                        Slog.i(TAG, "Sending new process state " + app.repProcState
16356                                + " to " + app /*, h*/);
16357                    }
16358                    app.thread.setProcessState(app.repProcState);
16359                } catch (RemoteException e) {
16360                }
16361            }
16362        }
16363        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16364                app.setProcState)) {
16365            app.lastStateTime = now;
16366            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16367                    isSleeping(), now);
16368            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16369                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16370                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16371                    + (app.nextPssTime-now) + ": " + app);
16372        } else {
16373            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16374                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16375                requestPssLocked(app, app.setProcState);
16376                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16377                        isSleeping(), now);
16378            } else if (false && DEBUG_PSS) {
16379                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16380            }
16381        }
16382        if (app.setProcState != app.curProcState) {
16383            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16384                    "Proc state change of " + app.processName
16385                    + " to " + app.curProcState);
16386            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16387            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16388            if (setImportant && !curImportant) {
16389                // This app is no longer something we consider important enough to allow to
16390                // use arbitrary amounts of battery power.  Note
16391                // its current wake lock time to later know to kill it if
16392                // it is not behaving well.
16393                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16394                synchronized (stats) {
16395                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16396                            app.pid, SystemClock.elapsedRealtime());
16397                }
16398                app.lastCpuTime = app.curCpuTime;
16399
16400            }
16401            app.setProcState = app.curProcState;
16402            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16403                app.notCachedSinceIdle = false;
16404            }
16405            if (!doingAll) {
16406                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16407            } else {
16408                app.procStateChanged = true;
16409            }
16410        }
16411
16412        if (changes != 0) {
16413            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16414            int i = mPendingProcessChanges.size()-1;
16415            ProcessChangeItem item = null;
16416            while (i >= 0) {
16417                item = mPendingProcessChanges.get(i);
16418                if (item.pid == app.pid) {
16419                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16420                    break;
16421                }
16422                i--;
16423            }
16424            if (i < 0) {
16425                // No existing item in pending changes; need a new one.
16426                final int NA = mAvailProcessChanges.size();
16427                if (NA > 0) {
16428                    item = mAvailProcessChanges.remove(NA-1);
16429                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16430                } else {
16431                    item = new ProcessChangeItem();
16432                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16433                }
16434                item.changes = 0;
16435                item.pid = app.pid;
16436                item.uid = app.info.uid;
16437                if (mPendingProcessChanges.size() == 0) {
16438                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16439                            "*** Enqueueing dispatch processes changed!");
16440                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16441                }
16442                mPendingProcessChanges.add(item);
16443            }
16444            item.changes |= changes;
16445            item.processState = app.repProcState;
16446            item.foregroundActivities = app.repForegroundActivities;
16447            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16448                    + Integer.toHexString(System.identityHashCode(item))
16449                    + " " + app.toShortString() + ": changes=" + item.changes
16450                    + " procState=" + item.processState
16451                    + " foreground=" + item.foregroundActivities
16452                    + " type=" + app.adjType + " source=" + app.adjSource
16453                    + " target=" + app.adjTarget);
16454        }
16455
16456        return success;
16457    }
16458
16459    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16460        if (proc.thread != null) {
16461            if (proc.baseProcessTracker != null) {
16462                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16463            }
16464            if (proc.repProcState >= 0) {
16465                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16466                        proc.repProcState);
16467            }
16468        }
16469    }
16470
16471    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16472            ProcessRecord TOP_APP, boolean doingAll, long now) {
16473        if (app.thread == null) {
16474            return false;
16475        }
16476
16477        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16478
16479        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16480    }
16481
16482    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16483            boolean oomAdj) {
16484        if (isForeground != proc.foregroundServices) {
16485            proc.foregroundServices = isForeground;
16486            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16487                    proc.info.uid);
16488            if (isForeground) {
16489                if (curProcs == null) {
16490                    curProcs = new ArrayList<ProcessRecord>();
16491                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16492                }
16493                if (!curProcs.contains(proc)) {
16494                    curProcs.add(proc);
16495                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16496                            proc.info.packageName, proc.info.uid);
16497                }
16498            } else {
16499                if (curProcs != null) {
16500                    if (curProcs.remove(proc)) {
16501                        mBatteryStatsService.noteEvent(
16502                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16503                                proc.info.packageName, proc.info.uid);
16504                        if (curProcs.size() <= 0) {
16505                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16506                        }
16507                    }
16508                }
16509            }
16510            if (oomAdj) {
16511                updateOomAdjLocked();
16512            }
16513        }
16514    }
16515
16516    private final ActivityRecord resumedAppLocked() {
16517        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16518        String pkg;
16519        int uid;
16520        if (act != null) {
16521            pkg = act.packageName;
16522            uid = act.info.applicationInfo.uid;
16523        } else {
16524            pkg = null;
16525            uid = -1;
16526        }
16527        // Has the UID or resumed package name changed?
16528        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16529                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16530            if (mCurResumedPackage != null) {
16531                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16532                        mCurResumedPackage, mCurResumedUid);
16533            }
16534            mCurResumedPackage = pkg;
16535            mCurResumedUid = uid;
16536            if (mCurResumedPackage != null) {
16537                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16538                        mCurResumedPackage, mCurResumedUid);
16539            }
16540        }
16541        return act;
16542    }
16543
16544    final boolean updateOomAdjLocked(ProcessRecord app) {
16545        final ActivityRecord TOP_ACT = resumedAppLocked();
16546        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16547        final boolean wasCached = app.cached;
16548
16549        mAdjSeq++;
16550
16551        // This is the desired cached adjusment we want to tell it to use.
16552        // If our app is currently cached, we know it, and that is it.  Otherwise,
16553        // we don't know it yet, and it needs to now be cached we will then
16554        // need to do a complete oom adj.
16555        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16556                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16557        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16558                SystemClock.uptimeMillis());
16559        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16560            // Changed to/from cached state, so apps after it in the LRU
16561            // list may also be changed.
16562            updateOomAdjLocked();
16563        }
16564        return success;
16565    }
16566
16567    final void updateOomAdjLocked() {
16568        final ActivityRecord TOP_ACT = resumedAppLocked();
16569        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16570        final long now = SystemClock.uptimeMillis();
16571        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16572        final int N = mLruProcesses.size();
16573
16574        if (false) {
16575            RuntimeException e = new RuntimeException();
16576            e.fillInStackTrace();
16577            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16578        }
16579
16580        mAdjSeq++;
16581        mNewNumServiceProcs = 0;
16582        mNewNumAServiceProcs = 0;
16583
16584        final int emptyProcessLimit;
16585        final int cachedProcessLimit;
16586        if (mProcessLimit <= 0) {
16587            emptyProcessLimit = cachedProcessLimit = 0;
16588        } else if (mProcessLimit == 1) {
16589            emptyProcessLimit = 1;
16590            cachedProcessLimit = 0;
16591        } else {
16592            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16593            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16594        }
16595
16596        // Let's determine how many processes we have running vs.
16597        // how many slots we have for background processes; we may want
16598        // to put multiple processes in a slot of there are enough of
16599        // them.
16600        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16601                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16602        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16603        if (numEmptyProcs > cachedProcessLimit) {
16604            // If there are more empty processes than our limit on cached
16605            // processes, then use the cached process limit for the factor.
16606            // This ensures that the really old empty processes get pushed
16607            // down to the bottom, so if we are running low on memory we will
16608            // have a better chance at keeping around more cached processes
16609            // instead of a gazillion empty processes.
16610            numEmptyProcs = cachedProcessLimit;
16611        }
16612        int emptyFactor = numEmptyProcs/numSlots;
16613        if (emptyFactor < 1) emptyFactor = 1;
16614        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16615        if (cachedFactor < 1) cachedFactor = 1;
16616        int stepCached = 0;
16617        int stepEmpty = 0;
16618        int numCached = 0;
16619        int numEmpty = 0;
16620        int numTrimming = 0;
16621
16622        mNumNonCachedProcs = 0;
16623        mNumCachedHiddenProcs = 0;
16624
16625        // First update the OOM adjustment for each of the
16626        // application processes based on their current state.
16627        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16628        int nextCachedAdj = curCachedAdj+1;
16629        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16630        int nextEmptyAdj = curEmptyAdj+2;
16631        for (int i=N-1; i>=0; i--) {
16632            ProcessRecord app = mLruProcesses.get(i);
16633            if (!app.killedByAm && app.thread != null) {
16634                app.procStateChanged = false;
16635                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16636
16637                // If we haven't yet assigned the final cached adj
16638                // to the process, do that now.
16639                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16640                    switch (app.curProcState) {
16641                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16642                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16643                            // This process is a cached process holding activities...
16644                            // assign it the next cached value for that type, and then
16645                            // step that cached level.
16646                            app.curRawAdj = curCachedAdj;
16647                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16648                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16649                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16650                                    + ")");
16651                            if (curCachedAdj != nextCachedAdj) {
16652                                stepCached++;
16653                                if (stepCached >= cachedFactor) {
16654                                    stepCached = 0;
16655                                    curCachedAdj = nextCachedAdj;
16656                                    nextCachedAdj += 2;
16657                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16658                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16659                                    }
16660                                }
16661                            }
16662                            break;
16663                        default:
16664                            // For everything else, assign next empty cached process
16665                            // level and bump that up.  Note that this means that
16666                            // long-running services that have dropped down to the
16667                            // cached level will be treated as empty (since their process
16668                            // state is still as a service), which is what we want.
16669                            app.curRawAdj = curEmptyAdj;
16670                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16671                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16672                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16673                                    + ")");
16674                            if (curEmptyAdj != nextEmptyAdj) {
16675                                stepEmpty++;
16676                                if (stepEmpty >= emptyFactor) {
16677                                    stepEmpty = 0;
16678                                    curEmptyAdj = nextEmptyAdj;
16679                                    nextEmptyAdj += 2;
16680                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16681                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16682                                    }
16683                                }
16684                            }
16685                            break;
16686                    }
16687                }
16688
16689                applyOomAdjLocked(app, TOP_APP, true, now);
16690
16691                // Count the number of process types.
16692                switch (app.curProcState) {
16693                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16694                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16695                        mNumCachedHiddenProcs++;
16696                        numCached++;
16697                        if (numCached > cachedProcessLimit) {
16698                            killUnneededProcessLocked(app, "cached #" + numCached);
16699                        }
16700                        break;
16701                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16702                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16703                                && app.lastActivityTime < oldTime) {
16704                            killUnneededProcessLocked(app, "empty for "
16705                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16706                                    / 1000) + "s");
16707                        } else {
16708                            numEmpty++;
16709                            if (numEmpty > emptyProcessLimit) {
16710                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16711                            }
16712                        }
16713                        break;
16714                    default:
16715                        mNumNonCachedProcs++;
16716                        break;
16717                }
16718
16719                if (app.isolated && app.services.size() <= 0) {
16720                    // If this is an isolated process, and there are no
16721                    // services running in it, then the process is no longer
16722                    // needed.  We agressively kill these because we can by
16723                    // definition not re-use the same process again, and it is
16724                    // good to avoid having whatever code was running in them
16725                    // left sitting around after no longer needed.
16726                    killUnneededProcessLocked(app, "isolated not needed");
16727                }
16728
16729                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16730                        && !app.killedByAm) {
16731                    numTrimming++;
16732                }
16733            }
16734        }
16735
16736        mNumServiceProcs = mNewNumServiceProcs;
16737
16738        // Now determine the memory trimming level of background processes.
16739        // Unfortunately we need to start at the back of the list to do this
16740        // properly.  We only do this if the number of background apps we
16741        // are managing to keep around is less than half the maximum we desire;
16742        // if we are keeping a good number around, we'll let them use whatever
16743        // memory they want.
16744        final int numCachedAndEmpty = numCached + numEmpty;
16745        int memFactor;
16746        if (numCached <= ProcessList.TRIM_CACHED_APPS
16747                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16748            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16749                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16750            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16751                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16752            } else {
16753                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16754            }
16755        } else {
16756            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16757        }
16758        // We always allow the memory level to go up (better).  We only allow it to go
16759        // down if we are in a state where that is allowed, *and* the total number of processes
16760        // has gone down since last time.
16761        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16762                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16763                + " last=" + mLastNumProcesses);
16764        if (memFactor > mLastMemoryLevel) {
16765            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16766                memFactor = mLastMemoryLevel;
16767                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16768            }
16769        }
16770        mLastMemoryLevel = memFactor;
16771        mLastNumProcesses = mLruProcesses.size();
16772        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16773        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16774        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16775            if (mLowRamStartTime == 0) {
16776                mLowRamStartTime = now;
16777            }
16778            int step = 0;
16779            int fgTrimLevel;
16780            switch (memFactor) {
16781                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16782                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16783                    break;
16784                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16785                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16786                    break;
16787                default:
16788                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16789                    break;
16790            }
16791            int factor = numTrimming/3;
16792            int minFactor = 2;
16793            if (mHomeProcess != null) minFactor++;
16794            if (mPreviousProcess != null) minFactor++;
16795            if (factor < minFactor) factor = minFactor;
16796            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16797            for (int i=N-1; i>=0; i--) {
16798                ProcessRecord app = mLruProcesses.get(i);
16799                if (allChanged || app.procStateChanged) {
16800                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16801                    app.procStateChanged = false;
16802                }
16803                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16804                        && !app.killedByAm) {
16805                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16806                        try {
16807                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16808                                    "Trimming memory of " + app.processName
16809                                    + " to " + curLevel);
16810                            app.thread.scheduleTrimMemory(curLevel);
16811                        } catch (RemoteException e) {
16812                        }
16813                        if (false) {
16814                            // For now we won't do this; our memory trimming seems
16815                            // to be good enough at this point that destroying
16816                            // activities causes more harm than good.
16817                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16818                                    && app != mHomeProcess && app != mPreviousProcess) {
16819                                // Need to do this on its own message because the stack may not
16820                                // be in a consistent state at this point.
16821                                // For these apps we will also finish their activities
16822                                // to help them free memory.
16823                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16824                            }
16825                        }
16826                    }
16827                    app.trimMemoryLevel = curLevel;
16828                    step++;
16829                    if (step >= factor) {
16830                        step = 0;
16831                        switch (curLevel) {
16832                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16833                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16834                                break;
16835                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16836                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16837                                break;
16838                        }
16839                    }
16840                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16841                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16842                            && app.thread != null) {
16843                        try {
16844                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16845                                    "Trimming memory of heavy-weight " + app.processName
16846                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16847                            app.thread.scheduleTrimMemory(
16848                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16849                        } catch (RemoteException e) {
16850                        }
16851                    }
16852                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16853                } else {
16854                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16855                            || app.systemNoUi) && app.pendingUiClean) {
16856                        // If this application is now in the background and it
16857                        // had done UI, then give it the special trim level to
16858                        // have it free UI resources.
16859                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16860                        if (app.trimMemoryLevel < level && app.thread != null) {
16861                            try {
16862                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16863                                        "Trimming memory of bg-ui " + app.processName
16864                                        + " to " + level);
16865                                app.thread.scheduleTrimMemory(level);
16866                            } catch (RemoteException e) {
16867                            }
16868                        }
16869                        app.pendingUiClean = false;
16870                    }
16871                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16872                        try {
16873                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16874                                    "Trimming memory of fg " + app.processName
16875                                    + " to " + fgTrimLevel);
16876                            app.thread.scheduleTrimMemory(fgTrimLevel);
16877                        } catch (RemoteException e) {
16878                        }
16879                    }
16880                    app.trimMemoryLevel = fgTrimLevel;
16881                }
16882            }
16883        } else {
16884            if (mLowRamStartTime != 0) {
16885                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16886                mLowRamStartTime = 0;
16887            }
16888            for (int i=N-1; i>=0; i--) {
16889                ProcessRecord app = mLruProcesses.get(i);
16890                if (allChanged || app.procStateChanged) {
16891                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16892                    app.procStateChanged = false;
16893                }
16894                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16895                        || app.systemNoUi) && app.pendingUiClean) {
16896                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16897                            && app.thread != null) {
16898                        try {
16899                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16900                                    "Trimming memory of ui hidden " + app.processName
16901                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16902                            app.thread.scheduleTrimMemory(
16903                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16904                        } catch (RemoteException e) {
16905                        }
16906                    }
16907                    app.pendingUiClean = false;
16908                }
16909                app.trimMemoryLevel = 0;
16910            }
16911        }
16912
16913        if (mAlwaysFinishActivities) {
16914            // Need to do this on its own message because the stack may not
16915            // be in a consistent state at this point.
16916            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16917        }
16918
16919        if (allChanged) {
16920            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16921        }
16922
16923        if (mProcessStats.shouldWriteNowLocked(now)) {
16924            mHandler.post(new Runnable() {
16925                @Override public void run() {
16926                    synchronized (ActivityManagerService.this) {
16927                        mProcessStats.writeStateAsyncLocked();
16928                    }
16929                }
16930            });
16931        }
16932
16933        if (DEBUG_OOM_ADJ) {
16934            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16935        }
16936    }
16937
16938    final void trimApplications() {
16939        synchronized (this) {
16940            int i;
16941
16942            // First remove any unused application processes whose package
16943            // has been removed.
16944            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16945                final ProcessRecord app = mRemovedProcesses.get(i);
16946                if (app.activities.size() == 0
16947                        && app.curReceiver == null && app.services.size() == 0) {
16948                    Slog.i(
16949                        TAG, "Exiting empty application process "
16950                        + app.processName + " ("
16951                        + (app.thread != null ? app.thread.asBinder() : null)
16952                        + ")\n");
16953                    if (app.pid > 0 && app.pid != MY_PID) {
16954                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16955                                app.processName, app.setAdj, "empty");
16956                        app.killedByAm = true;
16957                        Process.killProcessQuiet(app.pid);
16958                        Process.killProcessGroup(app.info.uid, app.pid);
16959                    } else {
16960                        try {
16961                            app.thread.scheduleExit();
16962                        } catch (Exception e) {
16963                            // Ignore exceptions.
16964                        }
16965                    }
16966                    cleanUpApplicationRecordLocked(app, false, true, -1);
16967                    mRemovedProcesses.remove(i);
16968
16969                    if (app.persistent) {
16970                        addAppLocked(app.info, false, null /* ABI override */);
16971                    }
16972                }
16973            }
16974
16975            // Now update the oom adj for all processes.
16976            updateOomAdjLocked();
16977        }
16978    }
16979
16980    /** This method sends the specified signal to each of the persistent apps */
16981    public void signalPersistentProcesses(int sig) throws RemoteException {
16982        if (sig != Process.SIGNAL_USR1) {
16983            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16984        }
16985
16986        synchronized (this) {
16987            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16988                    != PackageManager.PERMISSION_GRANTED) {
16989                throw new SecurityException("Requires permission "
16990                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16991            }
16992
16993            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16994                ProcessRecord r = mLruProcesses.get(i);
16995                if (r.thread != null && r.persistent) {
16996                    Process.sendSignal(r.pid, sig);
16997                }
16998            }
16999        }
17000    }
17001
17002    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
17003        if (proc == null || proc == mProfileProc) {
17004            proc = mProfileProc;
17005            path = mProfileFile;
17006            profileType = mProfileType;
17007            clearProfilerLocked();
17008        }
17009        if (proc == null) {
17010            return;
17011        }
17012        try {
17013            proc.thread.profilerControl(false, path, null, profileType);
17014        } catch (RemoteException e) {
17015            throw new IllegalStateException("Process disappeared");
17016        }
17017    }
17018
17019    private void clearProfilerLocked() {
17020        if (mProfileFd != null) {
17021            try {
17022                mProfileFd.close();
17023            } catch (IOException e) {
17024            }
17025        }
17026        mProfileApp = null;
17027        mProfileProc = null;
17028        mProfileFile = null;
17029        mProfileType = 0;
17030        mAutoStopProfiler = false;
17031    }
17032
17033    public boolean profileControl(String process, int userId, boolean start,
17034            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
17035
17036        try {
17037            synchronized (this) {
17038                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17039                // its own permission.
17040                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17041                        != PackageManager.PERMISSION_GRANTED) {
17042                    throw new SecurityException("Requires permission "
17043                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17044                }
17045
17046                if (start && fd == null) {
17047                    throw new IllegalArgumentException("null fd");
17048                }
17049
17050                ProcessRecord proc = null;
17051                if (process != null) {
17052                    proc = findProcessLocked(process, userId, "profileControl");
17053                }
17054
17055                if (start && (proc == null || proc.thread == null)) {
17056                    throw new IllegalArgumentException("Unknown process: " + process);
17057                }
17058
17059                if (start) {
17060                    stopProfilerLocked(null, null, 0);
17061                    setProfileApp(proc.info, proc.processName, path, fd, false);
17062                    mProfileProc = proc;
17063                    mProfileType = profileType;
17064                    try {
17065                        fd = fd.dup();
17066                    } catch (IOException e) {
17067                        fd = null;
17068                    }
17069                    proc.thread.profilerControl(start, path, fd, profileType);
17070                    fd = null;
17071                    mProfileFd = null;
17072                } else {
17073                    stopProfilerLocked(proc, path, profileType);
17074                    if (fd != null) {
17075                        try {
17076                            fd.close();
17077                        } catch (IOException e) {
17078                        }
17079                    }
17080                }
17081
17082                return true;
17083            }
17084        } catch (RemoteException e) {
17085            throw new IllegalStateException("Process disappeared");
17086        } finally {
17087            if (fd != null) {
17088                try {
17089                    fd.close();
17090                } catch (IOException e) {
17091                }
17092            }
17093        }
17094    }
17095
17096    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17097        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17098                userId, true, ALLOW_FULL_ONLY, callName, null);
17099        ProcessRecord proc = null;
17100        try {
17101            int pid = Integer.parseInt(process);
17102            synchronized (mPidsSelfLocked) {
17103                proc = mPidsSelfLocked.get(pid);
17104            }
17105        } catch (NumberFormatException e) {
17106        }
17107
17108        if (proc == null) {
17109            ArrayMap<String, SparseArray<ProcessRecord>> all
17110                    = mProcessNames.getMap();
17111            SparseArray<ProcessRecord> procs = all.get(process);
17112            if (procs != null && procs.size() > 0) {
17113                proc = procs.valueAt(0);
17114                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17115                    for (int i=1; i<procs.size(); i++) {
17116                        ProcessRecord thisProc = procs.valueAt(i);
17117                        if (thisProc.userId == userId) {
17118                            proc = thisProc;
17119                            break;
17120                        }
17121                    }
17122                }
17123            }
17124        }
17125
17126        return proc;
17127    }
17128
17129    public boolean dumpHeap(String process, int userId, boolean managed,
17130            String path, ParcelFileDescriptor fd) throws RemoteException {
17131
17132        try {
17133            synchronized (this) {
17134                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17135                // its own permission (same as profileControl).
17136                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17137                        != PackageManager.PERMISSION_GRANTED) {
17138                    throw new SecurityException("Requires permission "
17139                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17140                }
17141
17142                if (fd == null) {
17143                    throw new IllegalArgumentException("null fd");
17144                }
17145
17146                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17147                if (proc == null || proc.thread == null) {
17148                    throw new IllegalArgumentException("Unknown process: " + process);
17149                }
17150
17151                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17152                if (!isDebuggable) {
17153                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17154                        throw new SecurityException("Process not debuggable: " + proc);
17155                    }
17156                }
17157
17158                proc.thread.dumpHeap(managed, path, fd);
17159                fd = null;
17160                return true;
17161            }
17162        } catch (RemoteException e) {
17163            throw new IllegalStateException("Process disappeared");
17164        } finally {
17165            if (fd != null) {
17166                try {
17167                    fd.close();
17168                } catch (IOException e) {
17169                }
17170            }
17171        }
17172    }
17173
17174    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17175    public void monitor() {
17176        synchronized (this) { }
17177    }
17178
17179    void onCoreSettingsChange(Bundle settings) {
17180        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17181            ProcessRecord processRecord = mLruProcesses.get(i);
17182            try {
17183                if (processRecord.thread != null) {
17184                    processRecord.thread.setCoreSettings(settings);
17185                }
17186            } catch (RemoteException re) {
17187                /* ignore */
17188            }
17189        }
17190    }
17191
17192    // Multi-user methods
17193
17194    /**
17195     * Start user, if its not already running, but don't bring it to foreground.
17196     */
17197    @Override
17198    public boolean startUserInBackground(final int userId) {
17199        return startUser(userId, /* foreground */ false);
17200    }
17201
17202    /**
17203     * Refreshes the list of users related to the current user when either a
17204     * user switch happens or when a new related user is started in the
17205     * background.
17206     */
17207    private void updateCurrentProfileIdsLocked() {
17208        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17209                mCurrentUserId, false /* enabledOnly */);
17210        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17211        for (int i = 0; i < currentProfileIds.length; i++) {
17212            currentProfileIds[i] = profiles.get(i).id;
17213        }
17214        mCurrentProfileIds = currentProfileIds;
17215
17216        synchronized (mUserProfileGroupIdsSelfLocked) {
17217            mUserProfileGroupIdsSelfLocked.clear();
17218            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17219            for (int i = 0; i < users.size(); i++) {
17220                UserInfo user = users.get(i);
17221                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17222                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17223                }
17224            }
17225        }
17226    }
17227
17228    private Set getProfileIdsLocked(int userId) {
17229        Set userIds = new HashSet<Integer>();
17230        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17231                userId, false /* enabledOnly */);
17232        for (UserInfo user : profiles) {
17233            userIds.add(Integer.valueOf(user.id));
17234        }
17235        return userIds;
17236    }
17237
17238    @Override
17239    public boolean switchUser(final int userId) {
17240        return startUser(userId, /* foregound */ true);
17241    }
17242
17243    private boolean startUser(final int userId, boolean foreground) {
17244        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17245                != PackageManager.PERMISSION_GRANTED) {
17246            String msg = "Permission Denial: switchUser() from pid="
17247                    + Binder.getCallingPid()
17248                    + ", uid=" + Binder.getCallingUid()
17249                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17250            Slog.w(TAG, msg);
17251            throw new SecurityException(msg);
17252        }
17253
17254        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17255
17256        final long ident = Binder.clearCallingIdentity();
17257        try {
17258            synchronized (this) {
17259                final int oldUserId = mCurrentUserId;
17260                if (oldUserId == userId) {
17261                    return true;
17262                }
17263
17264                mStackSupervisor.setLockTaskModeLocked(null, false);
17265
17266                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17267                if (userInfo == null) {
17268                    Slog.w(TAG, "No user info for user #" + userId);
17269                    return false;
17270                }
17271                if (foreground && userInfo.isManagedProfile()) {
17272                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17273                    return false;
17274                }
17275
17276                if (foreground) {
17277                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17278                            R.anim.screen_user_enter);
17279                }
17280
17281                boolean needStart = false;
17282
17283                // If the user we are switching to is not currently started, then
17284                // we need to start it now.
17285                if (mStartedUsers.get(userId) == null) {
17286                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17287                    updateStartedUserArrayLocked();
17288                    needStart = true;
17289                }
17290
17291                final Integer userIdInt = Integer.valueOf(userId);
17292                mUserLru.remove(userIdInt);
17293                mUserLru.add(userIdInt);
17294
17295                if (foreground) {
17296                    mCurrentUserId = userId;
17297                    updateCurrentProfileIdsLocked();
17298                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17299                    // Once the internal notion of the active user has switched, we lock the device
17300                    // with the option to show the user switcher on the keyguard.
17301                    mWindowManager.lockNow(null);
17302                } else {
17303                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17304                    updateCurrentProfileIdsLocked();
17305                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17306                    mUserLru.remove(currentUserIdInt);
17307                    mUserLru.add(currentUserIdInt);
17308                }
17309
17310                final UserStartedState uss = mStartedUsers.get(userId);
17311
17312                // Make sure user is in the started state.  If it is currently
17313                // stopping, we need to knock that off.
17314                if (uss.mState == UserStartedState.STATE_STOPPING) {
17315                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17316                    // so we can just fairly silently bring the user back from
17317                    // the almost-dead.
17318                    uss.mState = UserStartedState.STATE_RUNNING;
17319                    updateStartedUserArrayLocked();
17320                    needStart = true;
17321                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17322                    // This means ACTION_SHUTDOWN has been sent, so we will
17323                    // need to treat this as a new boot of the user.
17324                    uss.mState = UserStartedState.STATE_BOOTING;
17325                    updateStartedUserArrayLocked();
17326                    needStart = true;
17327                }
17328
17329                if (uss.mState == UserStartedState.STATE_BOOTING) {
17330                    // Booting up a new user, need to tell system services about it.
17331                    // Note that this is on the same handler as scheduling of broadcasts,
17332                    // which is important because it needs to go first.
17333                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
17334                }
17335
17336                if (foreground) {
17337                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17338                            oldUserId));
17339                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17340                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17341                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17342                            oldUserId, userId, uss));
17343                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17344                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17345                }
17346
17347                if (needStart) {
17348                    // Send USER_STARTED broadcast
17349                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17350                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17351                            | Intent.FLAG_RECEIVER_FOREGROUND);
17352                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17353                    broadcastIntentLocked(null, null, intent,
17354                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17355                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17356                }
17357
17358                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17359                    if (userId != UserHandle.USER_OWNER) {
17360                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17361                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17362                        broadcastIntentLocked(null, null, intent, null,
17363                                new IIntentReceiver.Stub() {
17364                                    public void performReceive(Intent intent, int resultCode,
17365                                            String data, Bundle extras, boolean ordered,
17366                                            boolean sticky, int sendingUser) {
17367                                        userInitialized(uss, userId);
17368                                    }
17369                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17370                                true, false, MY_PID, Process.SYSTEM_UID,
17371                                userId);
17372                        uss.initializing = true;
17373                    } else {
17374                        getUserManagerLocked().makeInitialized(userInfo.id);
17375                    }
17376                }
17377
17378                if (foreground) {
17379                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17380                    if (homeInFront) {
17381                        startHomeActivityLocked(userId);
17382                    } else {
17383                        mStackSupervisor.resumeTopActivitiesLocked();
17384                    }
17385                    EventLogTags.writeAmSwitchUser(userId);
17386                    getUserManagerLocked().userForeground(userId);
17387                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17388                } else {
17389                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17390                }
17391
17392                if (needStart) {
17393                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17394                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17395                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17396                    broadcastIntentLocked(null, null, intent,
17397                            null, new IIntentReceiver.Stub() {
17398                                @Override
17399                                public void performReceive(Intent intent, int resultCode, String data,
17400                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17401                                        throws RemoteException {
17402                                }
17403                            }, 0, null, null,
17404                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17405                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17406                }
17407            }
17408        } finally {
17409            Binder.restoreCallingIdentity(ident);
17410        }
17411
17412        return true;
17413    }
17414
17415    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17416        long ident = Binder.clearCallingIdentity();
17417        try {
17418            Intent intent;
17419            if (oldUserId >= 0) {
17420                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17421                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17422                int count = profiles.size();
17423                for (int i = 0; i < count; i++) {
17424                    int profileUserId = profiles.get(i).id;
17425                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17426                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17427                            | Intent.FLAG_RECEIVER_FOREGROUND);
17428                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17429                    broadcastIntentLocked(null, null, intent,
17430                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17431                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17432                }
17433            }
17434            if (newUserId >= 0) {
17435                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17436                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17437                int count = profiles.size();
17438                for (int i = 0; i < count; i++) {
17439                    int profileUserId = profiles.get(i).id;
17440                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17441                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17442                            | Intent.FLAG_RECEIVER_FOREGROUND);
17443                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17444                    broadcastIntentLocked(null, null, intent,
17445                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17446                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17447                }
17448                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17449                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17450                        | Intent.FLAG_RECEIVER_FOREGROUND);
17451                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17452                broadcastIntentLocked(null, null, intent,
17453                        null, null, 0, null, null,
17454                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17455                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17456            }
17457        } finally {
17458            Binder.restoreCallingIdentity(ident);
17459        }
17460    }
17461
17462    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17463            final int newUserId) {
17464        final int N = mUserSwitchObservers.beginBroadcast();
17465        if (N > 0) {
17466            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17467                int mCount = 0;
17468                @Override
17469                public void sendResult(Bundle data) throws RemoteException {
17470                    synchronized (ActivityManagerService.this) {
17471                        if (mCurUserSwitchCallback == this) {
17472                            mCount++;
17473                            if (mCount == N) {
17474                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17475                            }
17476                        }
17477                    }
17478                }
17479            };
17480            synchronized (this) {
17481                uss.switching = true;
17482                mCurUserSwitchCallback = callback;
17483            }
17484            for (int i=0; i<N; i++) {
17485                try {
17486                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17487                            newUserId, callback);
17488                } catch (RemoteException e) {
17489                }
17490            }
17491        } else {
17492            synchronized (this) {
17493                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17494            }
17495        }
17496        mUserSwitchObservers.finishBroadcast();
17497    }
17498
17499    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17500        synchronized (this) {
17501            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17502            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17503        }
17504    }
17505
17506    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17507        mCurUserSwitchCallback = null;
17508        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17509        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17510                oldUserId, newUserId, uss));
17511    }
17512
17513    void userInitialized(UserStartedState uss, int newUserId) {
17514        completeSwitchAndInitalize(uss, newUserId, true, false);
17515    }
17516
17517    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17518        completeSwitchAndInitalize(uss, newUserId, false, true);
17519    }
17520
17521    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17522            boolean clearInitializing, boolean clearSwitching) {
17523        boolean unfrozen = false;
17524        synchronized (this) {
17525            if (clearInitializing) {
17526                uss.initializing = false;
17527                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17528            }
17529            if (clearSwitching) {
17530                uss.switching = false;
17531            }
17532            if (!uss.switching && !uss.initializing) {
17533                mWindowManager.stopFreezingScreen();
17534                unfrozen = true;
17535            }
17536        }
17537        if (unfrozen) {
17538            final int N = mUserSwitchObservers.beginBroadcast();
17539            for (int i=0; i<N; i++) {
17540                try {
17541                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17542                } catch (RemoteException e) {
17543                }
17544            }
17545            mUserSwitchObservers.finishBroadcast();
17546        }
17547    }
17548
17549    void scheduleStartProfilesLocked() {
17550        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17551            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17552                    DateUtils.SECOND_IN_MILLIS);
17553        }
17554    }
17555
17556    void startProfilesLocked() {
17557        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17558        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17559                mCurrentUserId, false /* enabledOnly */);
17560        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17561        for (UserInfo user : profiles) {
17562            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17563                    && user.id != mCurrentUserId) {
17564                toStart.add(user);
17565            }
17566        }
17567        final int n = toStart.size();
17568        int i = 0;
17569        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17570            startUserInBackground(toStart.get(i).id);
17571        }
17572        if (i < n) {
17573            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17574        }
17575    }
17576
17577    void finishUserBoot(UserStartedState uss) {
17578        synchronized (this) {
17579            if (uss.mState == UserStartedState.STATE_BOOTING
17580                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17581                uss.mState = UserStartedState.STATE_RUNNING;
17582                final int userId = uss.mHandle.getIdentifier();
17583                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17584                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17585                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17586                broadcastIntentLocked(null, null, intent,
17587                        null, null, 0, null, null,
17588                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17589                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17590            }
17591        }
17592    }
17593
17594    void finishUserSwitch(UserStartedState uss) {
17595        synchronized (this) {
17596            finishUserBoot(uss);
17597
17598            startProfilesLocked();
17599
17600            int num = mUserLru.size();
17601            int i = 0;
17602            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17603                Integer oldUserId = mUserLru.get(i);
17604                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17605                if (oldUss == null) {
17606                    // Shouldn't happen, but be sane if it does.
17607                    mUserLru.remove(i);
17608                    num--;
17609                    continue;
17610                }
17611                if (oldUss.mState == UserStartedState.STATE_STOPPING
17612                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17613                    // This user is already stopping, doesn't count.
17614                    num--;
17615                    i++;
17616                    continue;
17617                }
17618                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17619                    // Owner and current can't be stopped, but count as running.
17620                    i++;
17621                    continue;
17622                }
17623                // This is a user to be stopped.
17624                stopUserLocked(oldUserId, null);
17625                num--;
17626                i++;
17627            }
17628        }
17629    }
17630
17631    @Override
17632    public int stopUser(final int userId, final IStopUserCallback callback) {
17633        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17634                != PackageManager.PERMISSION_GRANTED) {
17635            String msg = "Permission Denial: switchUser() from pid="
17636                    + Binder.getCallingPid()
17637                    + ", uid=" + Binder.getCallingUid()
17638                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17639            Slog.w(TAG, msg);
17640            throw new SecurityException(msg);
17641        }
17642        if (userId <= 0) {
17643            throw new IllegalArgumentException("Can't stop primary user " + userId);
17644        }
17645        synchronized (this) {
17646            return stopUserLocked(userId, callback);
17647        }
17648    }
17649
17650    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17651        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17652        if (mCurrentUserId == userId) {
17653            return ActivityManager.USER_OP_IS_CURRENT;
17654        }
17655
17656        final UserStartedState uss = mStartedUsers.get(userId);
17657        if (uss == null) {
17658            // User is not started, nothing to do...  but we do need to
17659            // callback if requested.
17660            if (callback != null) {
17661                mHandler.post(new Runnable() {
17662                    @Override
17663                    public void run() {
17664                        try {
17665                            callback.userStopped(userId);
17666                        } catch (RemoteException e) {
17667                        }
17668                    }
17669                });
17670            }
17671            return ActivityManager.USER_OP_SUCCESS;
17672        }
17673
17674        if (callback != null) {
17675            uss.mStopCallbacks.add(callback);
17676        }
17677
17678        if (uss.mState != UserStartedState.STATE_STOPPING
17679                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17680            uss.mState = UserStartedState.STATE_STOPPING;
17681            updateStartedUserArrayLocked();
17682
17683            long ident = Binder.clearCallingIdentity();
17684            try {
17685                // We are going to broadcast ACTION_USER_STOPPING and then
17686                // once that is done send a final ACTION_SHUTDOWN and then
17687                // stop the user.
17688                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17689                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17690                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17691                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17692                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17693                // This is the result receiver for the final shutdown broadcast.
17694                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17695                    @Override
17696                    public void performReceive(Intent intent, int resultCode, String data,
17697                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17698                        finishUserStop(uss);
17699                    }
17700                };
17701                // This is the result receiver for the initial stopping broadcast.
17702                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17703                    @Override
17704                    public void performReceive(Intent intent, int resultCode, String data,
17705                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17706                        // On to the next.
17707                        synchronized (ActivityManagerService.this) {
17708                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17709                                // Whoops, we are being started back up.  Abort, abort!
17710                                return;
17711                            }
17712                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17713                        }
17714                        mBatteryStatsService.noteEvent(
17715                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17716                                Integer.toString(userId), userId);
17717                        mSystemServiceManager.stopUser(userId);
17718                        broadcastIntentLocked(null, null, shutdownIntent,
17719                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17720                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17721                    }
17722                };
17723                // Kick things off.
17724                broadcastIntentLocked(null, null, stoppingIntent,
17725                        null, stoppingReceiver, 0, null, null,
17726                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17727                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17728            } finally {
17729                Binder.restoreCallingIdentity(ident);
17730            }
17731        }
17732
17733        return ActivityManager.USER_OP_SUCCESS;
17734    }
17735
17736    void finishUserStop(UserStartedState uss) {
17737        final int userId = uss.mHandle.getIdentifier();
17738        boolean stopped;
17739        ArrayList<IStopUserCallback> callbacks;
17740        synchronized (this) {
17741            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17742            if (mStartedUsers.get(userId) != uss) {
17743                stopped = false;
17744            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17745                stopped = false;
17746            } else {
17747                stopped = true;
17748                // User can no longer run.
17749                mStartedUsers.remove(userId);
17750                mUserLru.remove(Integer.valueOf(userId));
17751                updateStartedUserArrayLocked();
17752
17753                // Clean up all state and processes associated with the user.
17754                // Kill all the processes for the user.
17755                forceStopUserLocked(userId, "finish user");
17756            }
17757
17758            // Explicitly remove the old information in mRecentTasks.
17759            removeRecentTasksForUserLocked(userId);
17760        }
17761
17762        for (int i=0; i<callbacks.size(); i++) {
17763            try {
17764                if (stopped) callbacks.get(i).userStopped(userId);
17765                else callbacks.get(i).userStopAborted(userId);
17766            } catch (RemoteException e) {
17767            }
17768        }
17769
17770        if (stopped) {
17771            mSystemServiceManager.cleanupUser(userId);
17772            synchronized (this) {
17773                mStackSupervisor.removeUserLocked(userId);
17774            }
17775        }
17776    }
17777
17778    @Override
17779    public UserInfo getCurrentUser() {
17780        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17781                != PackageManager.PERMISSION_GRANTED) && (
17782                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17783                != PackageManager.PERMISSION_GRANTED)) {
17784            String msg = "Permission Denial: getCurrentUser() from pid="
17785                    + Binder.getCallingPid()
17786                    + ", uid=" + Binder.getCallingUid()
17787                    + " requires " + INTERACT_ACROSS_USERS;
17788            Slog.w(TAG, msg);
17789            throw new SecurityException(msg);
17790        }
17791        synchronized (this) {
17792            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17793        }
17794    }
17795
17796    int getCurrentUserIdLocked() {
17797        return mCurrentUserId;
17798    }
17799
17800    @Override
17801    public boolean isUserRunning(int userId, boolean orStopped) {
17802        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17803                != PackageManager.PERMISSION_GRANTED) {
17804            String msg = "Permission Denial: isUserRunning() from pid="
17805                    + Binder.getCallingPid()
17806                    + ", uid=" + Binder.getCallingUid()
17807                    + " requires " + INTERACT_ACROSS_USERS;
17808            Slog.w(TAG, msg);
17809            throw new SecurityException(msg);
17810        }
17811        synchronized (this) {
17812            return isUserRunningLocked(userId, orStopped);
17813        }
17814    }
17815
17816    boolean isUserRunningLocked(int userId, boolean orStopped) {
17817        UserStartedState state = mStartedUsers.get(userId);
17818        if (state == null) {
17819            return false;
17820        }
17821        if (orStopped) {
17822            return true;
17823        }
17824        return state.mState != UserStartedState.STATE_STOPPING
17825                && state.mState != UserStartedState.STATE_SHUTDOWN;
17826    }
17827
17828    @Override
17829    public int[] getRunningUserIds() {
17830        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17831                != PackageManager.PERMISSION_GRANTED) {
17832            String msg = "Permission Denial: isUserRunning() from pid="
17833                    + Binder.getCallingPid()
17834                    + ", uid=" + Binder.getCallingUid()
17835                    + " requires " + INTERACT_ACROSS_USERS;
17836            Slog.w(TAG, msg);
17837            throw new SecurityException(msg);
17838        }
17839        synchronized (this) {
17840            return mStartedUserArray;
17841        }
17842    }
17843
17844    private void updateStartedUserArrayLocked() {
17845        int num = 0;
17846        for (int i=0; i<mStartedUsers.size();  i++) {
17847            UserStartedState uss = mStartedUsers.valueAt(i);
17848            // This list does not include stopping users.
17849            if (uss.mState != UserStartedState.STATE_STOPPING
17850                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17851                num++;
17852            }
17853        }
17854        mStartedUserArray = new int[num];
17855        num = 0;
17856        for (int i=0; i<mStartedUsers.size();  i++) {
17857            UserStartedState uss = mStartedUsers.valueAt(i);
17858            if (uss.mState != UserStartedState.STATE_STOPPING
17859                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17860                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17861                num++;
17862            }
17863        }
17864    }
17865
17866    @Override
17867    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17868        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17869                != PackageManager.PERMISSION_GRANTED) {
17870            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17871                    + Binder.getCallingPid()
17872                    + ", uid=" + Binder.getCallingUid()
17873                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17874            Slog.w(TAG, msg);
17875            throw new SecurityException(msg);
17876        }
17877
17878        mUserSwitchObservers.register(observer);
17879    }
17880
17881    @Override
17882    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17883        mUserSwitchObservers.unregister(observer);
17884    }
17885
17886    private boolean userExists(int userId) {
17887        if (userId == 0) {
17888            return true;
17889        }
17890        UserManagerService ums = getUserManagerLocked();
17891        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17892    }
17893
17894    int[] getUsersLocked() {
17895        UserManagerService ums = getUserManagerLocked();
17896        return ums != null ? ums.getUserIds() : new int[] { 0 };
17897    }
17898
17899    UserManagerService getUserManagerLocked() {
17900        if (mUserManager == null) {
17901            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17902            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17903        }
17904        return mUserManager;
17905    }
17906
17907    private int applyUserId(int uid, int userId) {
17908        return UserHandle.getUid(userId, uid);
17909    }
17910
17911    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17912        if (info == null) return null;
17913        ApplicationInfo newInfo = new ApplicationInfo(info);
17914        newInfo.uid = applyUserId(info.uid, userId);
17915        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17916                + info.packageName;
17917        return newInfo;
17918    }
17919
17920    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17921        if (aInfo == null
17922                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17923            return aInfo;
17924        }
17925
17926        ActivityInfo info = new ActivityInfo(aInfo);
17927        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17928        return info;
17929    }
17930
17931    private final class LocalService extends ActivityManagerInternal {
17932        @Override
17933        public void goingToSleep() {
17934            ActivityManagerService.this.goingToSleep();
17935        }
17936
17937        @Override
17938        public void wakingUp() {
17939            ActivityManagerService.this.wakingUp();
17940        }
17941
17942        @Override
17943        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
17944                String processName, String abiOverride, int uid, Runnable crashHandler) {
17945            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
17946                    processName, abiOverride, uid, crashHandler);
17947        }
17948    }
17949
17950    /**
17951     * An implementation of IAppTask, that allows an app to manage its own tasks via
17952     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17953     * only the process that calls getAppTasks() can call the AppTask methods.
17954     */
17955    class AppTaskImpl extends IAppTask.Stub {
17956        private int mTaskId;
17957        private int mCallingUid;
17958
17959        public AppTaskImpl(int taskId, int callingUid) {
17960            mTaskId = taskId;
17961            mCallingUid = callingUid;
17962        }
17963
17964        @Override
17965        public void finishAndRemoveTask() {
17966            // Ensure that we are called from the same process that created this AppTask
17967            if (mCallingUid != Binder.getCallingUid()) {
17968                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17969                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17970                return;
17971            }
17972
17973            synchronized (ActivityManagerService.this) {
17974                long origId = Binder.clearCallingIdentity();
17975                try {
17976                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17977                    if (tr != null) {
17978                        // Only kill the process if we are not a new document
17979                        int flags = tr.getBaseIntent().getFlags();
17980                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17981                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17982                        removeTaskByIdLocked(mTaskId,
17983                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17984                    }
17985                } finally {
17986                    Binder.restoreCallingIdentity(origId);
17987                }
17988            }
17989        }
17990
17991        @Override
17992        public ActivityManager.RecentTaskInfo getTaskInfo() {
17993            // Ensure that we are called from the same process that created this AppTask
17994            if (mCallingUid != Binder.getCallingUid()) {
17995                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17996                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17997                return null;
17998            }
17999
18000            synchronized (ActivityManagerService.this) {
18001                long origId = Binder.clearCallingIdentity();
18002                try {
18003                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18004                    if (tr != null) {
18005                        return createRecentTaskInfoFromTaskRecord(tr);
18006                    }
18007                } finally {
18008                    Binder.restoreCallingIdentity(origId);
18009                }
18010                return null;
18011            }
18012        }
18013    }
18014}
18015