ActivityManagerService.java revision d61dc20de10452dcc6905dcf0654f30c64762a1d
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
20import static android.content.pm.PackageManager.PERMISSION_GRANTED;
21import static com.android.internal.util.XmlUtils.readBooleanAttribute;
22import static com.android.internal.util.XmlUtils.readIntAttribute;
23import static com.android.internal.util.XmlUtils.readLongAttribute;
24import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
25import static com.android.internal.util.XmlUtils.writeIntAttribute;
26import static com.android.internal.util.XmlUtils.writeLongAttribute;
27import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
28import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
29import static org.xmlpull.v1.XmlPullParser.START_TAG;
30import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
31
32import android.Manifest;
33import android.app.AppOpsManager;
34import android.app.IActivityContainer;
35import android.app.IActivityContainerCallback;
36import android.app.IAppTask;
37import android.app.admin.DevicePolicyManager;
38import android.appwidget.AppWidgetManager;
39import android.graphics.Rect;
40import android.os.BatteryStats;
41import android.os.PersistableBundle;
42import android.service.voice.IVoiceInteractionSession;
43import android.util.ArrayMap;
44
45import com.android.internal.R;
46import com.android.internal.annotations.GuardedBy;
47import com.android.internal.app.IAppOpsService;
48import com.android.internal.app.IVoiceInteractor;
49import com.android.internal.app.ProcessMap;
50import com.android.internal.app.ProcessStats;
51import com.android.internal.content.PackageMonitor;
52import com.android.internal.os.BackgroundThread;
53import com.android.internal.os.BatteryStatsImpl;
54import com.android.internal.os.ProcessCpuTracker;
55import com.android.internal.os.TransferPipe;
56import com.android.internal.os.Zygote;
57import com.android.internal.util.FastPrintWriter;
58import com.android.internal.util.FastXmlSerializer;
59import com.android.internal.util.MemInfoReader;
60import com.android.internal.util.Preconditions;
61import com.android.server.AppOpsService;
62import com.android.server.AttributeCache;
63import com.android.server.IntentResolver;
64import com.android.server.LocalServices;
65import com.android.server.ServiceThread;
66import com.android.server.SystemService;
67import com.android.server.SystemServiceManager;
68import com.android.server.Watchdog;
69import com.android.server.am.ActivityStack.ActivityState;
70import com.android.server.firewall.IntentFirewall;
71import com.android.server.pm.UserManagerService;
72import com.android.server.wm.AppTransition;
73import com.android.server.wm.WindowManagerService;
74import com.google.android.collect.Lists;
75import com.google.android.collect.Maps;
76
77import libcore.io.IoUtils;
78
79import org.xmlpull.v1.XmlPullParser;
80import org.xmlpull.v1.XmlPullParserException;
81import org.xmlpull.v1.XmlSerializer;
82
83import android.app.Activity;
84import android.app.ActivityManager;
85import android.app.ActivityManager.RunningTaskInfo;
86import android.app.ActivityManager.StackInfo;
87import android.app.ActivityManagerInternal;
88import android.app.ActivityManagerNative;
89import android.app.ActivityOptions;
90import android.app.ActivityThread;
91import android.app.AlertDialog;
92import android.app.AppGlobals;
93import android.app.ApplicationErrorReport;
94import android.app.Dialog;
95import android.app.IActivityController;
96import android.app.IApplicationThread;
97import android.app.IInstrumentationWatcher;
98import android.app.INotificationManager;
99import android.app.IProcessObserver;
100import android.app.IServiceConnection;
101import android.app.IStopUserCallback;
102import android.app.IUiAutomationConnection;
103import android.app.IUserSwitchObserver;
104import android.app.Instrumentation;
105import android.app.Notification;
106import android.app.NotificationManager;
107import android.app.PendingIntent;
108import android.app.backup.IBackupManager;
109import android.content.ActivityNotFoundException;
110import android.content.BroadcastReceiver;
111import android.content.ClipData;
112import android.content.ComponentCallbacks2;
113import android.content.ComponentName;
114import android.content.ContentProvider;
115import android.content.ContentResolver;
116import android.content.Context;
117import android.content.DialogInterface;
118import android.content.IContentProvider;
119import android.content.IIntentReceiver;
120import android.content.IIntentSender;
121import android.content.Intent;
122import android.content.IntentFilter;
123import android.content.IntentSender;
124import android.content.pm.ActivityInfo;
125import android.content.pm.ApplicationInfo;
126import android.content.pm.ConfigurationInfo;
127import android.content.pm.IPackageDataObserver;
128import android.content.pm.IPackageManager;
129import android.content.pm.InstrumentationInfo;
130import android.content.pm.PackageInfo;
131import android.content.pm.PackageManager;
132import android.content.pm.ParceledListSlice;
133import android.content.pm.UserInfo;
134import android.content.pm.PackageManager.NameNotFoundException;
135import android.content.pm.PathPermission;
136import android.content.pm.ProviderInfo;
137import android.content.pm.ResolveInfo;
138import android.content.pm.ServiceInfo;
139import android.content.res.CompatibilityInfo;
140import android.content.res.Configuration;
141import android.graphics.Bitmap;
142import android.net.Proxy;
143import android.net.ProxyInfo;
144import android.net.Uri;
145import android.os.Binder;
146import android.os.Build;
147import android.os.Bundle;
148import android.os.Debug;
149import android.os.DropBoxManager;
150import android.os.Environment;
151import android.os.FactoryTest;
152import android.os.FileObserver;
153import android.os.FileUtils;
154import android.os.Handler;
155import android.os.IBinder;
156import android.os.IPermissionController;
157import android.os.IRemoteCallback;
158import android.os.IUserManager;
159import android.os.Looper;
160import android.os.Message;
161import android.os.Parcel;
162import android.os.ParcelFileDescriptor;
163import android.os.Process;
164import android.os.RemoteCallbackList;
165import android.os.RemoteException;
166import android.os.SELinux;
167import android.os.ServiceManager;
168import android.os.StrictMode;
169import android.os.SystemClock;
170import android.os.SystemProperties;
171import android.os.UpdateLock;
172import android.os.UserHandle;
173import android.provider.Settings;
174import android.text.format.DateUtils;
175import android.text.format.Time;
176import android.util.AtomicFile;
177import android.util.EventLog;
178import android.util.Log;
179import android.util.Pair;
180import android.util.PrintWriterPrinter;
181import android.util.Slog;
182import android.util.SparseArray;
183import android.util.TimeUtils;
184import android.util.Xml;
185import android.view.Gravity;
186import android.view.LayoutInflater;
187import android.view.View;
188import android.view.WindowManager;
189
190import java.io.BufferedInputStream;
191import java.io.BufferedOutputStream;
192import java.io.DataInputStream;
193import java.io.DataOutputStream;
194import java.io.File;
195import java.io.FileDescriptor;
196import java.io.FileInputStream;
197import java.io.FileNotFoundException;
198import java.io.FileOutputStream;
199import java.io.IOException;
200import java.io.InputStreamReader;
201import java.io.PrintWriter;
202import java.io.StringWriter;
203import java.lang.ref.WeakReference;
204import java.util.ArrayList;
205import java.util.Arrays;
206import java.util.Collections;
207import java.util.Comparator;
208import java.util.HashMap;
209import java.util.HashSet;
210import java.util.Iterator;
211import java.util.List;
212import java.util.Locale;
213import java.util.Map;
214import java.util.Set;
215import java.util.concurrent.atomic.AtomicBoolean;
216import java.util.concurrent.atomic.AtomicLong;
217
218public final class ActivityManagerService extends ActivityManagerNative
219        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
220    private static final String USER_DATA_DIR = "/data/user/";
221    static final String TAG = "ActivityManager";
222    static final String TAG_MU = "ActivityManagerServiceMU";
223    static final boolean DEBUG = false;
224    static final boolean localLOGV = DEBUG;
225    static final boolean DEBUG_BACKUP = localLOGV || false;
226    static final boolean DEBUG_BROADCAST = localLOGV || false;
227    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
228    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
229    static final boolean DEBUG_CLEANUP = localLOGV || false;
230    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
231    static final boolean DEBUG_FOCUS = false;
232    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
233    static final boolean DEBUG_MU = localLOGV || false;
234    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
235    static final boolean DEBUG_LRU = localLOGV || false;
236    static final boolean DEBUG_PAUSE = localLOGV || false;
237    static final boolean DEBUG_POWER = localLOGV || false;
238    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
239    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
240    static final boolean DEBUG_PROCESSES = localLOGV || false;
241    static final boolean DEBUG_PROVIDER = localLOGV || false;
242    static final boolean DEBUG_RESULTS = localLOGV || false;
243    static final boolean DEBUG_SERVICE = localLOGV || false;
244    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
245    static final boolean DEBUG_STACK = localLOGV || false;
246    static final boolean DEBUG_SWITCH = localLOGV || false;
247    static final boolean DEBUG_TASKS = localLOGV || false;
248    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
249    static final boolean DEBUG_TRANSITION = localLOGV || false;
250    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
251    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
252    static final boolean DEBUG_VISBILITY = localLOGV || false;
253    static final boolean DEBUG_PSS = localLOGV || false;
254    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
255    static final boolean VALIDATE_TOKENS = false;
256    static final boolean SHOW_ACTIVITY_START_TIME = true;
257
258    // Control over CPU and battery monitoring.
259    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
260    static final boolean MONITOR_CPU_USAGE = true;
261    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
262    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
263    static final boolean MONITOR_THREAD_CPU_USAGE = false;
264
265    // The flags that are set for all calls we make to the package manager.
266    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
267
268    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
269
270    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
271
272    // Maximum number of recent tasks that we can remember.
273    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
274
275    // Maximum number recent bitmaps to keep in memory.
276    static final int MAX_RECENT_BITMAPS = 5;
277
278    // Amount of time after a call to stopAppSwitches() during which we will
279    // prevent further untrusted switches from happening.
280    static final long APP_SWITCH_DELAY_TIME = 5*1000;
281
282    // How long we wait for a launched process to attach to the activity manager
283    // before we decide it's never going to come up for real.
284    static final int PROC_START_TIMEOUT = 10*1000;
285
286    // How long we wait for a launched process to attach to the activity manager
287    // before we decide it's never going to come up for real, when the process was
288    // started with a wrapper for instrumentation (such as Valgrind) because it
289    // could take much longer than usual.
290    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
291
292    // How long to wait after going idle before forcing apps to GC.
293    static final int GC_TIMEOUT = 5*1000;
294
295    // The minimum amount of time between successive GC requests for a process.
296    static final int GC_MIN_INTERVAL = 60*1000;
297
298    // The minimum amount of time between successive PSS requests for a process.
299    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
300
301    // The minimum amount of time between successive PSS requests for a process
302    // when the request is due to the memory state being lowered.
303    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
304
305    // The rate at which we check for apps using excessive power -- 15 mins.
306    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
307
308    // The minimum sample duration we will allow before deciding we have
309    // enough data on wake locks to start killing things.
310    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
311
312    // The minimum sample duration we will allow before deciding we have
313    // enough data on CPU usage to start killing things.
314    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
315
316    // How long we allow a receiver to run before giving up on it.
317    static final int BROADCAST_FG_TIMEOUT = 10*1000;
318    static final int BROADCAST_BG_TIMEOUT = 60*1000;
319
320    // How long we wait until we timeout on key dispatching.
321    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
322
323    // How long we wait until we timeout on key dispatching during instrumentation.
324    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
325
326    // Amount of time we wait for observers to handle a user switch before
327    // giving up on them and unfreezing the screen.
328    static final int USER_SWITCH_TIMEOUT = 2*1000;
329
330    // Maximum number of users we allow to be running at a time.
331    static final int MAX_RUNNING_USERS = 3;
332
333    // How long to wait in getAssistContextExtras for the activity and foreground services
334    // to respond with the result.
335    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
336
337    // Maximum number of persisted Uri grants a package is allowed
338    static final int MAX_PERSISTED_URI_GRANTS = 128;
339
340    static final int MY_PID = Process.myPid();
341
342    static final String[] EMPTY_STRING_ARRAY = new String[0];
343
344    // How many bytes to write into the dropbox log before truncating
345    static final int DROPBOX_MAX_SIZE = 256 * 1024;
346
347    /** All system services */
348    SystemServiceManager mSystemServiceManager;
349
350    /** Run all ActivityStacks through this */
351    ActivityStackSupervisor mStackSupervisor;
352
353    public IntentFirewall mIntentFirewall;
354
355    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
356    // default actuion automatically.  Important for devices without direct input
357    // devices.
358    private boolean mShowDialogs = true;
359
360    /**
361     * Description of a request to start a new activity, which has been held
362     * due to app switches being disabled.
363     */
364    static class PendingActivityLaunch {
365        final ActivityRecord r;
366        final ActivityRecord sourceRecord;
367        final int startFlags;
368        final ActivityStack stack;
369
370        PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
371                int _startFlags, ActivityStack _stack) {
372            r = _r;
373            sourceRecord = _sourceRecord;
374            startFlags = _startFlags;
375            stack = _stack;
376        }
377    }
378
379    final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
380            = new ArrayList<PendingActivityLaunch>();
381
382    BroadcastQueue mFgBroadcastQueue;
383    BroadcastQueue mBgBroadcastQueue;
384    // Convenient for easy iteration over the queues. Foreground is first
385    // so that dispatch of foreground broadcasts gets precedence.
386    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
387
388    BroadcastQueue broadcastQueueForIntent(Intent intent) {
389        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
390        if (DEBUG_BACKGROUND_BROADCAST) {
391            Slog.i(TAG, "Broadcast intent " + intent + " on "
392                    + (isFg ? "foreground" : "background")
393                    + " queue");
394        }
395        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
396    }
397
398    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
399        for (BroadcastQueue queue : mBroadcastQueues) {
400            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
401            if (r != null) {
402                return r;
403            }
404        }
405        return null;
406    }
407
408    /**
409     * Activity we have told the window manager to have key focus.
410     */
411    ActivityRecord mFocusedActivity = null;
412
413    /**
414     * List of intents that were used to start the most recent tasks.
415     */
416    ArrayList<TaskRecord> mRecentTasks;
417
418    public class PendingAssistExtras extends Binder implements Runnable {
419        public final ActivityRecord activity;
420        public boolean haveResult = false;
421        public Bundle result = null;
422        public PendingAssistExtras(ActivityRecord _activity) {
423            activity = _activity;
424        }
425        @Override
426        public void run() {
427            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
428            synchronized (this) {
429                haveResult = true;
430                notifyAll();
431            }
432        }
433    }
434
435    final ArrayList<PendingAssistExtras> mPendingAssistExtras
436            = new ArrayList<PendingAssistExtras>();
437
438    /**
439     * Process management.
440     */
441    final ProcessList mProcessList = new ProcessList();
442
443    /**
444     * All of the applications we currently have running organized by name.
445     * The keys are strings of the application package name (as
446     * returned by the package manager), and the keys are ApplicationRecord
447     * objects.
448     */
449    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
450
451    /**
452     * Tracking long-term execution of processes to look for abuse and other
453     * bad app behavior.
454     */
455    final ProcessStatsService mProcessStats;
456
457    /**
458     * The currently running isolated processes.
459     */
460    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
461
462    /**
463     * Counter for assigning isolated process uids, to avoid frequently reusing the
464     * same ones.
465     */
466    int mNextIsolatedProcessUid = 0;
467
468    /**
469     * The currently running heavy-weight process, if any.
470     */
471    ProcessRecord mHeavyWeightProcess = null;
472
473    /**
474     * The last time that various processes have crashed.
475     */
476    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
477
478    /**
479     * Information about a process that is currently marked as bad.
480     */
481    static final class BadProcessInfo {
482        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
483            this.time = time;
484            this.shortMsg = shortMsg;
485            this.longMsg = longMsg;
486            this.stack = stack;
487        }
488
489        final long time;
490        final String shortMsg;
491        final String longMsg;
492        final String stack;
493    }
494
495    /**
496     * Set of applications that we consider to be bad, and will reject
497     * incoming broadcasts from (which the user has no control over).
498     * Processes are added to this set when they have crashed twice within
499     * a minimum amount of time; they are removed from it when they are
500     * later restarted (hopefully due to some user action).  The value is the
501     * time it was added to the list.
502     */
503    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
504
505    /**
506     * All of the processes we currently have running organized by pid.
507     * The keys are the pid running the application.
508     *
509     * <p>NOTE: This object is protected by its own lock, NOT the global
510     * activity manager lock!
511     */
512    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
513
514    /**
515     * All of the processes that have been forced to be foreground.  The key
516     * is the pid of the caller who requested it (we hold a death
517     * link on it).
518     */
519    abstract class ForegroundToken implements IBinder.DeathRecipient {
520        int pid;
521        IBinder token;
522    }
523    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
524
525    /**
526     * List of records for processes that someone had tried to start before the
527     * system was ready.  We don't start them at that point, but ensure they
528     * are started by the time booting is complete.
529     */
530    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
531
532    /**
533     * List of persistent applications that are in the process
534     * of being started.
535     */
536    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * Processes that are being forcibly torn down.
540     */
541    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
542
543    /**
544     * List of running applications, sorted by recent usage.
545     * The first entry in the list is the least recently used.
546     */
547    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
548
549    /**
550     * Where in mLruProcesses that the processes hosting activities start.
551     */
552    int mLruProcessActivityStart = 0;
553
554    /**
555     * Where in mLruProcesses that the processes hosting services start.
556     * This is after (lower index) than mLruProcessesActivityStart.
557     */
558    int mLruProcessServiceStart = 0;
559
560    /**
561     * List of processes that should gc as soon as things are idle.
562     */
563    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
564
565    /**
566     * Processes we want to collect PSS data from.
567     */
568    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
569
570    /**
571     * Last time we requested PSS data of all processes.
572     */
573    long mLastFullPssTime = SystemClock.uptimeMillis();
574
575    /**
576     * If set, the next time we collect PSS data we should do a full collection
577     * with data from native processes and the kernel.
578     */
579    boolean mFullPssPending = false;
580
581    /**
582     * This is the process holding what we currently consider to be
583     * the "home" activity.
584     */
585    ProcessRecord mHomeProcess;
586
587    /**
588     * This is the process holding the activity the user last visited that
589     * is in a different process from the one they are currently in.
590     */
591    ProcessRecord mPreviousProcess;
592
593    /**
594     * The time at which the previous process was last visible.
595     */
596    long mPreviousProcessVisibleTime;
597
598    /**
599     * Which uses have been started, so are allowed to run code.
600     */
601    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
602
603    /**
604     * LRU list of history of current users.  Most recently current is at the end.
605     */
606    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
607
608    /**
609     * Constant array of the users that are currently started.
610     */
611    int[] mStartedUserArray = new int[] { 0 };
612
613    /**
614     * Registered observers of the user switching mechanics.
615     */
616    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
617            = new RemoteCallbackList<IUserSwitchObserver>();
618
619    /**
620     * Currently active user switch.
621     */
622    Object mCurUserSwitchCallback;
623
624    /**
625     * Packages that the user has asked to have run in screen size
626     * compatibility mode instead of filling the screen.
627     */
628    final CompatModePackages mCompatModePackages;
629
630    /**
631     * Set of IntentSenderRecord objects that are currently active.
632     */
633    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
634            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
635
636    /**
637     * Fingerprints (hashCode()) of stack traces that we've
638     * already logged DropBox entries for.  Guarded by itself.  If
639     * something (rogue user app) forces this over
640     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
641     */
642    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
643    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
644
645    /**
646     * Strict Mode background batched logging state.
647     *
648     * The string buffer is guarded by itself, and its lock is also
649     * used to determine if another batched write is already
650     * in-flight.
651     */
652    private final StringBuilder mStrictModeBuffer = new StringBuilder();
653
654    /**
655     * Keeps track of all IIntentReceivers that have been registered for
656     * broadcasts.  Hash keys are the receiver IBinder, hash value is
657     * a ReceiverList.
658     */
659    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
660            new HashMap<IBinder, ReceiverList>();
661
662    /**
663     * Resolver for broadcast intents to registered receivers.
664     * Holds BroadcastFilter (subclass of IntentFilter).
665     */
666    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
667            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
668        @Override
669        protected boolean allowFilterResult(
670                BroadcastFilter filter, List<BroadcastFilter> dest) {
671            IBinder target = filter.receiverList.receiver.asBinder();
672            for (int i=dest.size()-1; i>=0; i--) {
673                if (dest.get(i).receiverList.receiver.asBinder() == target) {
674                    return false;
675                }
676            }
677            return true;
678        }
679
680        @Override
681        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
682            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
683                    || userId == filter.owningUserId) {
684                return super.newResult(filter, match, userId);
685            }
686            return null;
687        }
688
689        @Override
690        protected BroadcastFilter[] newArray(int size) {
691            return new BroadcastFilter[size];
692        }
693
694        @Override
695        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
696            return packageName.equals(filter.packageName);
697        }
698    };
699
700    /**
701     * State of all active sticky broadcasts per user.  Keys are the action of the
702     * sticky Intent, values are an ArrayList of all broadcasted intents with
703     * that action (which should usually be one).  The SparseArray is keyed
704     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
705     * for stickies that are sent to all users.
706     */
707    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
708            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
709
710    final ActiveServices mServices;
711
712    /**
713     * Backup/restore process management
714     */
715    String mBackupAppName = null;
716    BackupRecord mBackupTarget = null;
717
718    final ProviderMap mProviderMap;
719
720    /**
721     * List of content providers who have clients waiting for them.  The
722     * application is currently being launched and the provider will be
723     * removed from this list once it is published.
724     */
725    final ArrayList<ContentProviderRecord> mLaunchingProviders
726            = new ArrayList<ContentProviderRecord>();
727
728    /**
729     * File storing persisted {@link #mGrantedUriPermissions}.
730     */
731    private final AtomicFile mGrantFile;
732
733    /** XML constants used in {@link #mGrantFile} */
734    private static final String TAG_URI_GRANTS = "uri-grants";
735    private static final String TAG_URI_GRANT = "uri-grant";
736    private static final String ATTR_USER_HANDLE = "userHandle";
737    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
738    private static final String ATTR_TARGET_USER_ID = "targetUserId";
739    private static final String ATTR_SOURCE_PKG = "sourcePkg";
740    private static final String ATTR_TARGET_PKG = "targetPkg";
741    private static final String ATTR_URI = "uri";
742    private static final String ATTR_MODE_FLAGS = "modeFlags";
743    private static final String ATTR_CREATED_TIME = "createdTime";
744    private static final String ATTR_PREFIX = "prefix";
745
746    /**
747     * Global set of specific {@link Uri} permissions that have been granted.
748     * This optimized lookup structure maps from {@link UriPermission#targetUid}
749     * to {@link UriPermission#uri} to {@link UriPermission}.
750     */
751    @GuardedBy("this")
752    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
753            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
754
755    public static class GrantUri {
756        public final int sourceUserId;
757        public final Uri uri;
758        public boolean prefix;
759
760        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
761            this.sourceUserId = sourceUserId;
762            this.uri = uri;
763            this.prefix = prefix;
764        }
765
766        @Override
767        public int hashCode() {
768            return toString().hashCode();
769        }
770
771        @Override
772        public boolean equals(Object o) {
773            if (o instanceof GrantUri) {
774                GrantUri other = (GrantUri) o;
775                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
776                        && prefix == other.prefix;
777            }
778            return false;
779        }
780
781        @Override
782        public String toString() {
783            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
784            if (prefix) result += " [prefix]";
785            return result;
786        }
787
788        public String toSafeString() {
789            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
790            if (prefix) result += " [prefix]";
791            return result;
792        }
793
794        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
795            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
796                    ContentProvider.getUriWithoutUserId(uri), false);
797        }
798    }
799
800    CoreSettingsObserver mCoreSettingsObserver;
801
802    /**
803     * Thread-local storage used to carry caller permissions over through
804     * indirect content-provider access.
805     */
806    private class Identity {
807        public int pid;
808        public int uid;
809
810        Identity(int _pid, int _uid) {
811            pid = _pid;
812            uid = _uid;
813        }
814    }
815
816    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
817
818    /**
819     * All information we have collected about the runtime performance of
820     * any user id that can impact battery performance.
821     */
822    final BatteryStatsService mBatteryStatsService;
823
824    /**
825     * Information about component usage
826     */
827    final UsageStatsService mUsageStatsService;
828
829    /**
830     * Information about and control over application operations
831     */
832    final AppOpsService mAppOpsService;
833
834    /**
835     * Save recent tasks information across reboots.
836     */
837    final TaskPersister mTaskPersister;
838
839    /**
840     * Current configuration information.  HistoryRecord objects are given
841     * a reference to this object to indicate which configuration they are
842     * currently running in, so this object must be kept immutable.
843     */
844    Configuration mConfiguration = new Configuration();
845
846    /**
847     * Current sequencing integer of the configuration, for skipping old
848     * configurations.
849     */
850    int mConfigurationSeq = 0;
851
852    /**
853     * Hardware-reported OpenGLES version.
854     */
855    final int GL_ES_VERSION;
856
857    /**
858     * List of initialization arguments to pass to all processes when binding applications to them.
859     * For example, references to the commonly used services.
860     */
861    HashMap<String, IBinder> mAppBindArgs;
862
863    /**
864     * Temporary to avoid allocations.  Protected by main lock.
865     */
866    final StringBuilder mStringBuilder = new StringBuilder(256);
867
868    /**
869     * Used to control how we initialize the service.
870     */
871    ComponentName mTopComponent;
872    String mTopAction = Intent.ACTION_MAIN;
873    String mTopData;
874    boolean mProcessesReady = false;
875    boolean mSystemReady = false;
876    boolean mBooting = false;
877    boolean mWaitingUpdate = false;
878    boolean mDidUpdate = false;
879    boolean mOnBattery = false;
880    boolean mLaunchWarningShown = false;
881
882    Context mContext;
883
884    int mFactoryTest;
885
886    boolean mCheckedForSetup;
887
888    /**
889     * The time at which we will allow normal application switches again,
890     * after a call to {@link #stopAppSwitches()}.
891     */
892    long mAppSwitchesAllowedTime;
893
894    /**
895     * This is set to true after the first switch after mAppSwitchesAllowedTime
896     * is set; any switches after that will clear the time.
897     */
898    boolean mDidAppSwitch;
899
900    /**
901     * Last time (in realtime) at which we checked for power usage.
902     */
903    long mLastPowerCheckRealtime;
904
905    /**
906     * Last time (in uptime) at which we checked for power usage.
907     */
908    long mLastPowerCheckUptime;
909
910    /**
911     * Set while we are wanting to sleep, to prevent any
912     * activities from being started/resumed.
913     */
914    private boolean mSleeping = false;
915
916    /**
917     * Set while we are running a voice interaction.  This overrides
918     * sleeping while it is active.
919     */
920    private boolean mRunningVoice = false;
921
922    /**
923     * State of external calls telling us if the device is asleep.
924     */
925    private boolean mWentToSleep = false;
926
927    /**
928     * State of external call telling us if the lock screen is shown.
929     */
930    private boolean mLockScreenShown = false;
931
932    /**
933     * Set if we are shutting down the system, similar to sleeping.
934     */
935    boolean mShuttingDown = false;
936
937    /**
938     * Current sequence id for oom_adj computation traversal.
939     */
940    int mAdjSeq = 0;
941
942    /**
943     * Current sequence id for process LRU updating.
944     */
945    int mLruSeq = 0;
946
947    /**
948     * Keep track of the non-cached/empty process we last found, to help
949     * determine how to distribute cached/empty processes next time.
950     */
951    int mNumNonCachedProcs = 0;
952
953    /**
954     * Keep track of the number of cached hidden procs, to balance oom adj
955     * distribution between those and empty procs.
956     */
957    int mNumCachedHiddenProcs = 0;
958
959    /**
960     * Keep track of the number of service processes we last found, to
961     * determine on the next iteration which should be B services.
962     */
963    int mNumServiceProcs = 0;
964    int mNewNumAServiceProcs = 0;
965    int mNewNumServiceProcs = 0;
966
967    /**
968     * Allow the current computed overall memory level of the system to go down?
969     * This is set to false when we are killing processes for reasons other than
970     * memory management, so that the now smaller process list will not be taken as
971     * an indication that memory is tighter.
972     */
973    boolean mAllowLowerMemLevel = false;
974
975    /**
976     * The last computed memory level, for holding when we are in a state that
977     * processes are going away for other reasons.
978     */
979    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
980
981    /**
982     * The last total number of process we have, to determine if changes actually look
983     * like a shrinking number of process due to lower RAM.
984     */
985    int mLastNumProcesses;
986
987    /**
988     * The uptime of the last time we performed idle maintenance.
989     */
990    long mLastIdleTime = SystemClock.uptimeMillis();
991
992    /**
993     * Total time spent with RAM that has been added in the past since the last idle time.
994     */
995    long mLowRamTimeSinceLastIdle = 0;
996
997    /**
998     * If RAM is currently low, when that horrible situation started.
999     */
1000    long mLowRamStartTime = 0;
1001
1002    /**
1003     * For reporting to battery stats the current top application.
1004     */
1005    private String mCurResumedPackage = null;
1006    private int mCurResumedUid = -1;
1007
1008    /**
1009     * For reporting to battery stats the apps currently running foreground
1010     * service.  The ProcessMap is package/uid tuples; each of these contain
1011     * an array of the currently foreground processes.
1012     */
1013    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1014            = new ProcessMap<ArrayList<ProcessRecord>>();
1015
1016    /**
1017     * This is set if we had to do a delayed dexopt of an app before launching
1018     * it, to increase the ANR timeouts in that case.
1019     */
1020    boolean mDidDexOpt;
1021
1022    /**
1023     * Set if the systemServer made a call to enterSafeMode.
1024     */
1025    boolean mSafeMode;
1026
1027    String mDebugApp = null;
1028    boolean mWaitForDebugger = false;
1029    boolean mDebugTransient = false;
1030    String mOrigDebugApp = null;
1031    boolean mOrigWaitForDebugger = false;
1032    boolean mAlwaysFinishActivities = false;
1033    IActivityController mController = null;
1034    String mProfileApp = null;
1035    ProcessRecord mProfileProc = null;
1036    String mProfileFile;
1037    ParcelFileDescriptor mProfileFd;
1038    int mProfileType = 0;
1039    boolean mAutoStopProfiler = false;
1040    String mOpenGlTraceApp = null;
1041
1042    static class ProcessChangeItem {
1043        static final int CHANGE_ACTIVITIES = 1<<0;
1044        static final int CHANGE_PROCESS_STATE = 1<<1;
1045        int changes;
1046        int uid;
1047        int pid;
1048        int processState;
1049        boolean foregroundActivities;
1050    }
1051
1052    final RemoteCallbackList<IProcessObserver> mProcessObservers
1053            = new RemoteCallbackList<IProcessObserver>();
1054    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1055
1056    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1057            = new ArrayList<ProcessChangeItem>();
1058    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1059            = new ArrayList<ProcessChangeItem>();
1060
1061    /**
1062     * Runtime CPU use collection thread.  This object's lock is used to
1063     * protect all related state.
1064     */
1065    final Thread mProcessCpuThread;
1066
1067    /**
1068     * Used to collect process stats when showing not responding dialog.
1069     * Protected by mProcessCpuThread.
1070     */
1071    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1072            MONITOR_THREAD_CPU_USAGE);
1073    final AtomicLong mLastCpuTime = new AtomicLong(0);
1074    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1075
1076    long mLastWriteTime = 0;
1077
1078    /**
1079     * Used to retain an update lock when the foreground activity is in
1080     * immersive mode.
1081     */
1082    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1083
1084    /**
1085     * Set to true after the system has finished booting.
1086     */
1087    boolean mBooted = false;
1088
1089    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1090    int mProcessLimitOverride = -1;
1091
1092    WindowManagerService mWindowManager;
1093
1094    final ActivityThread mSystemThread;
1095
1096    int mCurrentUserId = 0;
1097    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1098    private UserManagerService mUserManager;
1099
1100    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1101        final ProcessRecord mApp;
1102        final int mPid;
1103        final IApplicationThread mAppThread;
1104
1105        AppDeathRecipient(ProcessRecord app, int pid,
1106                IApplicationThread thread) {
1107            if (localLOGV) Slog.v(
1108                TAG, "New death recipient " + this
1109                + " for thread " + thread.asBinder());
1110            mApp = app;
1111            mPid = pid;
1112            mAppThread = thread;
1113        }
1114
1115        @Override
1116        public void binderDied() {
1117            if (localLOGV) Slog.v(
1118                TAG, "Death received in " + this
1119                + " for thread " + mAppThread.asBinder());
1120            synchronized(ActivityManagerService.this) {
1121                appDiedLocked(mApp, mPid, mAppThread);
1122            }
1123        }
1124    }
1125
1126    static final int SHOW_ERROR_MSG = 1;
1127    static final int SHOW_NOT_RESPONDING_MSG = 2;
1128    static final int SHOW_FACTORY_ERROR_MSG = 3;
1129    static final int UPDATE_CONFIGURATION_MSG = 4;
1130    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1131    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1132    static final int SERVICE_TIMEOUT_MSG = 12;
1133    static final int UPDATE_TIME_ZONE = 13;
1134    static final int SHOW_UID_ERROR_MSG = 14;
1135    static final int IM_FEELING_LUCKY_MSG = 15;
1136    static final int PROC_START_TIMEOUT_MSG = 20;
1137    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1138    static final int KILL_APPLICATION_MSG = 22;
1139    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1140    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1141    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1142    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1143    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1144    static final int CLEAR_DNS_CACHE_MSG = 28;
1145    static final int UPDATE_HTTP_PROXY_MSG = 29;
1146    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1147    static final int DISPATCH_PROCESSES_CHANGED = 31;
1148    static final int DISPATCH_PROCESS_DIED = 32;
1149    static final int REPORT_MEM_USAGE_MSG = 33;
1150    static final int REPORT_USER_SWITCH_MSG = 34;
1151    static final int CONTINUE_USER_SWITCH_MSG = 35;
1152    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1153    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1154    static final int PERSIST_URI_GRANTS_MSG = 38;
1155    static final int REQUEST_ALL_PSS_MSG = 39;
1156    static final int START_PROFILES_MSG = 40;
1157    static final int UPDATE_TIME = 41;
1158    static final int SYSTEM_USER_START_MSG = 42;
1159    static final int SYSTEM_USER_CURRENT_MSG = 43;
1160
1161    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1162    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1163    static final int FIRST_COMPAT_MODE_MSG = 300;
1164    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1165
1166    AlertDialog mUidAlert;
1167    CompatModeDialog mCompatModeDialog;
1168    long mLastMemUsageReportTime = 0;
1169
1170    private LockToAppRequestDialog mLockToAppRequest;
1171
1172    /**
1173     * Flag whether the current user is a "monkey", i.e. whether
1174     * the UI is driven by a UI automation tool.
1175     */
1176    private boolean mUserIsMonkey;
1177
1178    final ServiceThread mHandlerThread;
1179    final MainHandler mHandler;
1180
1181    final class MainHandler extends Handler {
1182        public MainHandler(Looper looper) {
1183            super(looper, null, true);
1184        }
1185
1186        @Override
1187        public void handleMessage(Message msg) {
1188            switch (msg.what) {
1189            case SHOW_ERROR_MSG: {
1190                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1191                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1192                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1193                synchronized (ActivityManagerService.this) {
1194                    ProcessRecord proc = (ProcessRecord)data.get("app");
1195                    AppErrorResult res = (AppErrorResult) data.get("result");
1196                    if (proc != null && proc.crashDialog != null) {
1197                        Slog.e(TAG, "App already has crash dialog: " + proc);
1198                        if (res != null) {
1199                            res.set(0);
1200                        }
1201                        return;
1202                    }
1203                    if (!showBackground && UserHandle.getAppId(proc.uid)
1204                            >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
1205                            && proc.pid != MY_PID) {
1206                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1207                        if (res != null) {
1208                            res.set(0);
1209                        }
1210                        return;
1211                    }
1212                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1213                        Dialog d = new AppErrorDialog(mContext,
1214                                ActivityManagerService.this, res, proc);
1215                        d.show();
1216                        proc.crashDialog = d;
1217                    } else {
1218                        // The device is asleep, so just pretend that the user
1219                        // saw a crash dialog and hit "force quit".
1220                        if (res != null) {
1221                            res.set(0);
1222                        }
1223                    }
1224                }
1225
1226                ensureBootCompleted();
1227            } break;
1228            case SHOW_NOT_RESPONDING_MSG: {
1229                synchronized (ActivityManagerService.this) {
1230                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1231                    ProcessRecord proc = (ProcessRecord)data.get("app");
1232                    if (proc != null && proc.anrDialog != null) {
1233                        Slog.e(TAG, "App already has anr dialog: " + proc);
1234                        return;
1235                    }
1236
1237                    Intent intent = new Intent("android.intent.action.ANR");
1238                    if (!mProcessesReady) {
1239                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1240                                | Intent.FLAG_RECEIVER_FOREGROUND);
1241                    }
1242                    broadcastIntentLocked(null, null, intent,
1243                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1244                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1245
1246                    if (mShowDialogs) {
1247                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1248                                mContext, proc, (ActivityRecord)data.get("activity"),
1249                                msg.arg1 != 0);
1250                        d.show();
1251                        proc.anrDialog = d;
1252                    } else {
1253                        // Just kill the app if there is no dialog to be shown.
1254                        killAppAtUsersRequest(proc, null);
1255                    }
1256                }
1257
1258                ensureBootCompleted();
1259            } break;
1260            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1261                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1262                synchronized (ActivityManagerService.this) {
1263                    ProcessRecord proc = (ProcessRecord) data.get("app");
1264                    if (proc == null) {
1265                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1266                        break;
1267                    }
1268                    if (proc.crashDialog != null) {
1269                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1270                        return;
1271                    }
1272                    AppErrorResult res = (AppErrorResult) data.get("result");
1273                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1274                        Dialog d = new StrictModeViolationDialog(mContext,
1275                                ActivityManagerService.this, res, proc);
1276                        d.show();
1277                        proc.crashDialog = d;
1278                    } else {
1279                        // The device is asleep, so just pretend that the user
1280                        // saw a crash dialog and hit "force quit".
1281                        res.set(0);
1282                    }
1283                }
1284                ensureBootCompleted();
1285            } break;
1286            case SHOW_FACTORY_ERROR_MSG: {
1287                Dialog d = new FactoryErrorDialog(
1288                    mContext, msg.getData().getCharSequence("msg"));
1289                d.show();
1290                ensureBootCompleted();
1291            } break;
1292            case UPDATE_CONFIGURATION_MSG: {
1293                final ContentResolver resolver = mContext.getContentResolver();
1294                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1295            } break;
1296            case GC_BACKGROUND_PROCESSES_MSG: {
1297                synchronized (ActivityManagerService.this) {
1298                    performAppGcsIfAppropriateLocked();
1299                }
1300            } break;
1301            case WAIT_FOR_DEBUGGER_MSG: {
1302                synchronized (ActivityManagerService.this) {
1303                    ProcessRecord app = (ProcessRecord)msg.obj;
1304                    if (msg.arg1 != 0) {
1305                        if (!app.waitedForDebugger) {
1306                            Dialog d = new AppWaitingForDebuggerDialog(
1307                                    ActivityManagerService.this,
1308                                    mContext, app);
1309                            app.waitDialog = d;
1310                            app.waitedForDebugger = true;
1311                            d.show();
1312                        }
1313                    } else {
1314                        if (app.waitDialog != null) {
1315                            app.waitDialog.dismiss();
1316                            app.waitDialog = null;
1317                        }
1318                    }
1319                }
1320            } break;
1321            case SERVICE_TIMEOUT_MSG: {
1322                if (mDidDexOpt) {
1323                    mDidDexOpt = false;
1324                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1325                    nmsg.obj = msg.obj;
1326                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1327                    return;
1328                }
1329                mServices.serviceTimeout((ProcessRecord)msg.obj);
1330            } break;
1331            case UPDATE_TIME_ZONE: {
1332                synchronized (ActivityManagerService.this) {
1333                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1334                        ProcessRecord r = mLruProcesses.get(i);
1335                        if (r.thread != null) {
1336                            try {
1337                                r.thread.updateTimeZone();
1338                            } catch (RemoteException ex) {
1339                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1340                            }
1341                        }
1342                    }
1343                }
1344            } break;
1345            case CLEAR_DNS_CACHE_MSG: {
1346                synchronized (ActivityManagerService.this) {
1347                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1348                        ProcessRecord r = mLruProcesses.get(i);
1349                        if (r.thread != null) {
1350                            try {
1351                                r.thread.clearDnsCache();
1352                            } catch (RemoteException ex) {
1353                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1354                            }
1355                        }
1356                    }
1357                }
1358            } break;
1359            case UPDATE_HTTP_PROXY_MSG: {
1360                ProxyInfo proxy = (ProxyInfo)msg.obj;
1361                String host = "";
1362                String port = "";
1363                String exclList = "";
1364                Uri pacFileUrl = Uri.EMPTY;
1365                if (proxy != null) {
1366                    host = proxy.getHost();
1367                    port = Integer.toString(proxy.getPort());
1368                    exclList = proxy.getExclusionListAsString();
1369                    pacFileUrl = proxy.getPacFileUrl();
1370                }
1371                synchronized (ActivityManagerService.this) {
1372                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1373                        ProcessRecord r = mLruProcesses.get(i);
1374                        if (r.thread != null) {
1375                            try {
1376                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1377                            } catch (RemoteException ex) {
1378                                Slog.w(TAG, "Failed to update http proxy for: " +
1379                                        r.info.processName);
1380                            }
1381                        }
1382                    }
1383                }
1384            } break;
1385            case SHOW_UID_ERROR_MSG: {
1386                String title = "System UIDs Inconsistent";
1387                String text = "UIDs on the system are inconsistent, you need to wipe your"
1388                        + " data partition or your device will be unstable.";
1389                Log.e(TAG, title + ": " + text);
1390                if (mShowDialogs) {
1391                    // XXX This is a temporary dialog, no need to localize.
1392                    AlertDialog d = new BaseErrorDialog(mContext);
1393                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1394                    d.setCancelable(false);
1395                    d.setTitle(title);
1396                    d.setMessage(text);
1397                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1398                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1399                    mUidAlert = d;
1400                    d.show();
1401                }
1402            } break;
1403            case IM_FEELING_LUCKY_MSG: {
1404                if (mUidAlert != null) {
1405                    mUidAlert.dismiss();
1406                    mUidAlert = null;
1407                }
1408            } break;
1409            case PROC_START_TIMEOUT_MSG: {
1410                if (mDidDexOpt) {
1411                    mDidDexOpt = false;
1412                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1413                    nmsg.obj = msg.obj;
1414                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1415                    return;
1416                }
1417                ProcessRecord app = (ProcessRecord)msg.obj;
1418                synchronized (ActivityManagerService.this) {
1419                    processStartTimedOutLocked(app);
1420                }
1421            } break;
1422            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1423                synchronized (ActivityManagerService.this) {
1424                    doPendingActivityLaunchesLocked(true);
1425                }
1426            } break;
1427            case KILL_APPLICATION_MSG: {
1428                synchronized (ActivityManagerService.this) {
1429                    int appid = msg.arg1;
1430                    boolean restart = (msg.arg2 == 1);
1431                    Bundle bundle = (Bundle)msg.obj;
1432                    String pkg = bundle.getString("pkg");
1433                    String reason = bundle.getString("reason");
1434                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1435                            false, UserHandle.USER_ALL, reason);
1436                }
1437            } break;
1438            case FINALIZE_PENDING_INTENT_MSG: {
1439                ((PendingIntentRecord)msg.obj).completeFinalize();
1440            } break;
1441            case POST_HEAVY_NOTIFICATION_MSG: {
1442                INotificationManager inm = NotificationManager.getService();
1443                if (inm == null) {
1444                    return;
1445                }
1446
1447                ActivityRecord root = (ActivityRecord)msg.obj;
1448                ProcessRecord process = root.app;
1449                if (process == null) {
1450                    return;
1451                }
1452
1453                try {
1454                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1455                    String text = mContext.getString(R.string.heavy_weight_notification,
1456                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1457                    Notification notification = new Notification();
1458                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1459                    notification.when = 0;
1460                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1461                    notification.tickerText = text;
1462                    notification.defaults = 0; // please be quiet
1463                    notification.sound = null;
1464                    notification.vibrate = null;
1465                    notification.setLatestEventInfo(context, text,
1466                            mContext.getText(R.string.heavy_weight_notification_detail),
1467                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1468                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1469                                    new UserHandle(root.userId)));
1470
1471                    try {
1472                        int[] outId = new int[1];
1473                        inm.enqueueNotificationWithTag("android", "android", null,
1474                                R.string.heavy_weight_notification,
1475                                notification, outId, root.userId);
1476                    } catch (RuntimeException e) {
1477                        Slog.w(ActivityManagerService.TAG,
1478                                "Error showing notification for heavy-weight app", e);
1479                    } catch (RemoteException e) {
1480                    }
1481                } catch (NameNotFoundException e) {
1482                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1483                }
1484            } break;
1485            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1486                INotificationManager inm = NotificationManager.getService();
1487                if (inm == null) {
1488                    return;
1489                }
1490                try {
1491                    inm.cancelNotificationWithTag("android", null,
1492                            R.string.heavy_weight_notification,  msg.arg1);
1493                } catch (RuntimeException e) {
1494                    Slog.w(ActivityManagerService.TAG,
1495                            "Error canceling notification for service", e);
1496                } catch (RemoteException e) {
1497                }
1498            } break;
1499            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1500                synchronized (ActivityManagerService.this) {
1501                    checkExcessivePowerUsageLocked(true);
1502                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1503                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1504                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1505                }
1506            } break;
1507            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1508                synchronized (ActivityManagerService.this) {
1509                    ActivityRecord ar = (ActivityRecord)msg.obj;
1510                    if (mCompatModeDialog != null) {
1511                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1512                                ar.info.applicationInfo.packageName)) {
1513                            return;
1514                        }
1515                        mCompatModeDialog.dismiss();
1516                        mCompatModeDialog = null;
1517                    }
1518                    if (ar != null && false) {
1519                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1520                                ar.packageName)) {
1521                            int mode = mCompatModePackages.computeCompatModeLocked(
1522                                    ar.info.applicationInfo);
1523                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1524                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1525                                mCompatModeDialog = new CompatModeDialog(
1526                                        ActivityManagerService.this, mContext,
1527                                        ar.info.applicationInfo);
1528                                mCompatModeDialog.show();
1529                            }
1530                        }
1531                    }
1532                }
1533                break;
1534            }
1535            case DISPATCH_PROCESSES_CHANGED: {
1536                dispatchProcessesChanged();
1537                break;
1538            }
1539            case DISPATCH_PROCESS_DIED: {
1540                final int pid = msg.arg1;
1541                final int uid = msg.arg2;
1542                dispatchProcessDied(pid, uid);
1543                break;
1544            }
1545            case REPORT_MEM_USAGE_MSG: {
1546                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1547                Thread thread = new Thread() {
1548                    @Override public void run() {
1549                        final SparseArray<ProcessMemInfo> infoMap
1550                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1551                        for (int i=0, N=memInfos.size(); i<N; i++) {
1552                            ProcessMemInfo mi = memInfos.get(i);
1553                            infoMap.put(mi.pid, mi);
1554                        }
1555                        updateCpuStatsNow();
1556                        synchronized (mProcessCpuThread) {
1557                            final int N = mProcessCpuTracker.countStats();
1558                            for (int i=0; i<N; i++) {
1559                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1560                                if (st.vsize > 0) {
1561                                    long pss = Debug.getPss(st.pid, null);
1562                                    if (pss > 0) {
1563                                        if (infoMap.indexOfKey(st.pid) < 0) {
1564                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1565                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1566                                            mi.pss = pss;
1567                                            memInfos.add(mi);
1568                                        }
1569                                    }
1570                                }
1571                            }
1572                        }
1573
1574                        long totalPss = 0;
1575                        for (int i=0, N=memInfos.size(); i<N; i++) {
1576                            ProcessMemInfo mi = memInfos.get(i);
1577                            if (mi.pss == 0) {
1578                                mi.pss = Debug.getPss(mi.pid, null);
1579                            }
1580                            totalPss += mi.pss;
1581                        }
1582                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1583                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1584                                if (lhs.oomAdj != rhs.oomAdj) {
1585                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1586                                }
1587                                if (lhs.pss != rhs.pss) {
1588                                    return lhs.pss < rhs.pss ? 1 : -1;
1589                                }
1590                                return 0;
1591                            }
1592                        });
1593
1594                        StringBuilder tag = new StringBuilder(128);
1595                        StringBuilder stack = new StringBuilder(128);
1596                        tag.append("Low on memory -- ");
1597                        appendMemBucket(tag, totalPss, "total", false);
1598                        appendMemBucket(stack, totalPss, "total", true);
1599
1600                        StringBuilder logBuilder = new StringBuilder(1024);
1601                        logBuilder.append("Low on memory:\n");
1602
1603                        boolean firstLine = true;
1604                        int lastOomAdj = Integer.MIN_VALUE;
1605                        for (int i=0, N=memInfos.size(); i<N; i++) {
1606                            ProcessMemInfo mi = memInfos.get(i);
1607
1608                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1609                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1610                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1611                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1612                                if (lastOomAdj != mi.oomAdj) {
1613                                    lastOomAdj = mi.oomAdj;
1614                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1615                                        tag.append(" / ");
1616                                    }
1617                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1618                                        if (firstLine) {
1619                                            stack.append(":");
1620                                            firstLine = false;
1621                                        }
1622                                        stack.append("\n\t at ");
1623                                    } else {
1624                                        stack.append("$");
1625                                    }
1626                                } else {
1627                                    tag.append(" ");
1628                                    stack.append("$");
1629                                }
1630                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1631                                    appendMemBucket(tag, mi.pss, mi.name, false);
1632                                }
1633                                appendMemBucket(stack, mi.pss, mi.name, true);
1634                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1635                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1636                                    stack.append("(");
1637                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1638                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1639                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1640                                            stack.append(":");
1641                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1642                                        }
1643                                    }
1644                                    stack.append(")");
1645                                }
1646                            }
1647
1648                            logBuilder.append("  ");
1649                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1650                            logBuilder.append(' ');
1651                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1652                            logBuilder.append(' ');
1653                            ProcessList.appendRamKb(logBuilder, mi.pss);
1654                            logBuilder.append(" kB: ");
1655                            logBuilder.append(mi.name);
1656                            logBuilder.append(" (");
1657                            logBuilder.append(mi.pid);
1658                            logBuilder.append(") ");
1659                            logBuilder.append(mi.adjType);
1660                            logBuilder.append('\n');
1661                            if (mi.adjReason != null) {
1662                                logBuilder.append("                      ");
1663                                logBuilder.append(mi.adjReason);
1664                                logBuilder.append('\n');
1665                            }
1666                        }
1667
1668                        logBuilder.append("           ");
1669                        ProcessList.appendRamKb(logBuilder, totalPss);
1670                        logBuilder.append(" kB: TOTAL\n");
1671
1672                        long[] infos = new long[Debug.MEMINFO_COUNT];
1673                        Debug.getMemInfo(infos);
1674                        logBuilder.append("  MemInfo: ");
1675                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1676                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1677                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1678                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1679                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1680                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1681                            logBuilder.append("  ZRAM: ");
1682                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1683                            logBuilder.append(" kB RAM, ");
1684                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1685                            logBuilder.append(" kB swap total, ");
1686                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1687                            logBuilder.append(" kB swap free\n");
1688                        }
1689                        Slog.i(TAG, logBuilder.toString());
1690
1691                        StringBuilder dropBuilder = new StringBuilder(1024);
1692                        /*
1693                        StringWriter oomSw = new StringWriter();
1694                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1695                        StringWriter catSw = new StringWriter();
1696                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1697                        String[] emptyArgs = new String[] { };
1698                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1699                        oomPw.flush();
1700                        String oomString = oomSw.toString();
1701                        */
1702                        dropBuilder.append(stack);
1703                        dropBuilder.append('\n');
1704                        dropBuilder.append('\n');
1705                        dropBuilder.append(logBuilder);
1706                        dropBuilder.append('\n');
1707                        /*
1708                        dropBuilder.append(oomString);
1709                        dropBuilder.append('\n');
1710                        */
1711                        StringWriter catSw = new StringWriter();
1712                        synchronized (ActivityManagerService.this) {
1713                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1714                            String[] emptyArgs = new String[] { };
1715                            catPw.println();
1716                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1717                            catPw.println();
1718                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1719                                    false, false, null);
1720                            catPw.println();
1721                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1722                            catPw.flush();
1723                        }
1724                        dropBuilder.append(catSw.toString());
1725                        addErrorToDropBox("lowmem", null, "system_server", null,
1726                                null, tag.toString(), dropBuilder.toString(), null, null);
1727                        //Slog.i(TAG, "Sent to dropbox:");
1728                        //Slog.i(TAG, dropBuilder.toString());
1729                        synchronized (ActivityManagerService.this) {
1730                            long now = SystemClock.uptimeMillis();
1731                            if (mLastMemUsageReportTime < now) {
1732                                mLastMemUsageReportTime = now;
1733                            }
1734                        }
1735                    }
1736                };
1737                thread.start();
1738                break;
1739            }
1740            case REPORT_USER_SWITCH_MSG: {
1741                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1742                break;
1743            }
1744            case CONTINUE_USER_SWITCH_MSG: {
1745                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1746                break;
1747            }
1748            case USER_SWITCH_TIMEOUT_MSG: {
1749                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1750                break;
1751            }
1752            case IMMERSIVE_MODE_LOCK_MSG: {
1753                final boolean nextState = (msg.arg1 != 0);
1754                if (mUpdateLock.isHeld() != nextState) {
1755                    if (DEBUG_IMMERSIVE) {
1756                        final ActivityRecord r = (ActivityRecord) msg.obj;
1757                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1758                    }
1759                    if (nextState) {
1760                        mUpdateLock.acquire();
1761                    } else {
1762                        mUpdateLock.release();
1763                    }
1764                }
1765                break;
1766            }
1767            case PERSIST_URI_GRANTS_MSG: {
1768                writeGrantedUriPermissions();
1769                break;
1770            }
1771            case REQUEST_ALL_PSS_MSG: {
1772                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1773                break;
1774            }
1775            case START_PROFILES_MSG: {
1776                synchronized (ActivityManagerService.this) {
1777                    startProfilesLocked();
1778                }
1779                break;
1780            }
1781            case UPDATE_TIME: {
1782                synchronized (ActivityManagerService.this) {
1783                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1784                        ProcessRecord r = mLruProcesses.get(i);
1785                        if (r.thread != null) {
1786                            try {
1787                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1788                            } catch (RemoteException ex) {
1789                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1790                            }
1791                        }
1792                    }
1793                }
1794                break;
1795            }
1796            case SYSTEM_USER_START_MSG: {
1797                mSystemServiceManager.startUser(msg.arg1);
1798                break;
1799            }
1800            case SYSTEM_USER_CURRENT_MSG: {
1801                mSystemServiceManager.switchUser(msg.arg1);
1802                break;
1803            }
1804            }
1805        }
1806    };
1807
1808    static final int COLLECT_PSS_BG_MSG = 1;
1809
1810    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1811        @Override
1812        public void handleMessage(Message msg) {
1813            switch (msg.what) {
1814            case COLLECT_PSS_BG_MSG: {
1815                long start = SystemClock.uptimeMillis();
1816                MemInfoReader memInfo = null;
1817                synchronized (ActivityManagerService.this) {
1818                    if (mFullPssPending) {
1819                        mFullPssPending = false;
1820                        memInfo = new MemInfoReader();
1821                    }
1822                }
1823                if (memInfo != null) {
1824                    updateCpuStatsNow();
1825                    long nativeTotalPss = 0;
1826                    synchronized (mProcessCpuThread) {
1827                        final int N = mProcessCpuTracker.countStats();
1828                        for (int j=0; j<N; j++) {
1829                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1830                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1831                                // This is definitely an application process; skip it.
1832                                continue;
1833                            }
1834                            synchronized (mPidsSelfLocked) {
1835                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1836                                    // This is one of our own processes; skip it.
1837                                    continue;
1838                                }
1839                            }
1840                            nativeTotalPss += Debug.getPss(st.pid, null);
1841                        }
1842                    }
1843                    memInfo.readMemInfo();
1844                    synchronized (this) {
1845                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1846                                + (SystemClock.uptimeMillis()-start) + "ms");
1847                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1848                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1849                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1850                                        +memInfo.getSlabSizeKb(),
1851                                nativeTotalPss);
1852                    }
1853                }
1854
1855                int i=0, num=0;
1856                long[] tmp = new long[1];
1857                do {
1858                    ProcessRecord proc;
1859                    int procState;
1860                    int pid;
1861                    synchronized (ActivityManagerService.this) {
1862                        if (i >= mPendingPssProcesses.size()) {
1863                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1864                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1865                            mPendingPssProcesses.clear();
1866                            return;
1867                        }
1868                        proc = mPendingPssProcesses.get(i);
1869                        procState = proc.pssProcState;
1870                        if (proc.thread != null && procState == proc.setProcState) {
1871                            pid = proc.pid;
1872                        } else {
1873                            proc = null;
1874                            pid = 0;
1875                        }
1876                        i++;
1877                    }
1878                    if (proc != null) {
1879                        long pss = Debug.getPss(pid, tmp);
1880                        synchronized (ActivityManagerService.this) {
1881                            if (proc.thread != null && proc.setProcState == procState
1882                                    && proc.pid == pid) {
1883                                num++;
1884                                proc.lastPssTime = SystemClock.uptimeMillis();
1885                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1886                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1887                                        + ": " + pss + " lastPss=" + proc.lastPss
1888                                        + " state=" + ProcessList.makeProcStateString(procState));
1889                                if (proc.initialIdlePss == 0) {
1890                                    proc.initialIdlePss = pss;
1891                                }
1892                                proc.lastPss = pss;
1893                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1894                                    proc.lastCachedPss = pss;
1895                                }
1896                            }
1897                        }
1898                    }
1899                } while (true);
1900            }
1901            }
1902        }
1903    };
1904
1905    /**
1906     * Monitor for package changes and update our internal state.
1907     */
1908    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1909        @Override
1910        public void onPackageRemoved(String packageName, int uid) {
1911            // Remove all tasks with activities in the specified package from the list of recent tasks
1912            synchronized (ActivityManagerService.this) {
1913                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1914                    TaskRecord tr = mRecentTasks.get(i);
1915                    ComponentName cn = tr.intent.getComponent();
1916                    if (cn != null && cn.getPackageName().equals(packageName)) {
1917                        // If the package name matches, remove the task and kill the process
1918                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1919                    }
1920                }
1921            }
1922        }
1923
1924        @Override
1925        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1926            onPackageModified(packageName);
1927            return true;
1928        }
1929
1930        @Override
1931        public void onPackageModified(String packageName) {
1932            final PackageManager pm = mContext.getPackageManager();
1933            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1934                    new ArrayList<Pair<Intent, Integer>>();
1935            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1936            // Copy the list of recent tasks so that we don't hold onto the lock on
1937            // ActivityManagerService for long periods while checking if components exist.
1938            synchronized (ActivityManagerService.this) {
1939                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1940                    TaskRecord tr = mRecentTasks.get(i);
1941                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1942                }
1943            }
1944            // Check the recent tasks and filter out all tasks with components that no longer exist.
1945            Intent tmpI = new Intent();
1946            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1947                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1948                ComponentName cn = p.first.getComponent();
1949                if (cn != null && cn.getPackageName().equals(packageName)) {
1950                    try {
1951                        // Add the task to the list to remove if the component no longer exists
1952                        tmpI.setComponent(cn);
1953                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1954                            tasksToRemove.add(p.second);
1955                        }
1956                    } catch (Exception e) {}
1957                }
1958            }
1959            // Prune all the tasks with removed components from the list of recent tasks
1960            synchronized (ActivityManagerService.this) {
1961                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1962                    // Remove the task but don't kill the process (since other components in that
1963                    // package may still be running and in the background)
1964                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1965                }
1966            }
1967        }
1968
1969        @Override
1970        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
1971            // Force stop the specified packages
1972            if (packages != null) {
1973                for (String pkg : packages) {
1974                    synchronized (ActivityManagerService.this) {
1975                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
1976                                "finished booting")) {
1977                            return true;
1978                        }
1979                    }
1980                }
1981            }
1982            return false;
1983        }
1984    };
1985
1986    public void setSystemProcess() {
1987        try {
1988            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
1989            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
1990            ServiceManager.addService("meminfo", new MemBinder(this));
1991            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
1992            ServiceManager.addService("dbinfo", new DbBinder(this));
1993            if (MONITOR_CPU_USAGE) {
1994                ServiceManager.addService("cpuinfo", new CpuBinder(this));
1995            }
1996            ServiceManager.addService("permission", new PermissionController(this));
1997
1998            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
1999                    "android", STOCK_PM_FLAGS);
2000            mSystemThread.installSystemApplicationInfo(info);
2001
2002            synchronized (this) {
2003                ProcessRecord app = newProcessRecordLocked(info, info.processName, false);
2004                app.persistent = true;
2005                app.pid = MY_PID;
2006                app.maxAdj = ProcessList.SYSTEM_ADJ;
2007                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2008                mProcessNames.put(app.processName, app.uid, app);
2009                synchronized (mPidsSelfLocked) {
2010                    mPidsSelfLocked.put(app.pid, app);
2011                }
2012                updateLruProcessLocked(app, false, null);
2013                updateOomAdjLocked();
2014            }
2015        } catch (PackageManager.NameNotFoundException e) {
2016            throw new RuntimeException(
2017                    "Unable to find android system package", e);
2018        }
2019    }
2020
2021    public void setWindowManager(WindowManagerService wm) {
2022        mWindowManager = wm;
2023        mStackSupervisor.setWindowManager(wm);
2024    }
2025
2026    public void startObservingNativeCrashes() {
2027        final NativeCrashListener ncl = new NativeCrashListener(this);
2028        ncl.start();
2029    }
2030
2031    public IAppOpsService getAppOpsService() {
2032        return mAppOpsService;
2033    }
2034
2035    static class MemBinder extends Binder {
2036        ActivityManagerService mActivityManagerService;
2037        MemBinder(ActivityManagerService activityManagerService) {
2038            mActivityManagerService = activityManagerService;
2039        }
2040
2041        @Override
2042        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2043            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2044                    != PackageManager.PERMISSION_GRANTED) {
2045                pw.println("Permission Denial: can't dump meminfo from from pid="
2046                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2047                        + " without permission " + android.Manifest.permission.DUMP);
2048                return;
2049            }
2050
2051            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2052        }
2053    }
2054
2055    static class GraphicsBinder extends Binder {
2056        ActivityManagerService mActivityManagerService;
2057        GraphicsBinder(ActivityManagerService activityManagerService) {
2058            mActivityManagerService = activityManagerService;
2059        }
2060
2061        @Override
2062        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2063            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2064                    != PackageManager.PERMISSION_GRANTED) {
2065                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2066                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2067                        + " without permission " + android.Manifest.permission.DUMP);
2068                return;
2069            }
2070
2071            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2072        }
2073    }
2074
2075    static class DbBinder extends Binder {
2076        ActivityManagerService mActivityManagerService;
2077        DbBinder(ActivityManagerService activityManagerService) {
2078            mActivityManagerService = activityManagerService;
2079        }
2080
2081        @Override
2082        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2083            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2084                    != PackageManager.PERMISSION_GRANTED) {
2085                pw.println("Permission Denial: can't dump dbinfo from from pid="
2086                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2087                        + " without permission " + android.Manifest.permission.DUMP);
2088                return;
2089            }
2090
2091            mActivityManagerService.dumpDbInfo(fd, pw, args);
2092        }
2093    }
2094
2095    static class CpuBinder extends Binder {
2096        ActivityManagerService mActivityManagerService;
2097        CpuBinder(ActivityManagerService activityManagerService) {
2098            mActivityManagerService = activityManagerService;
2099        }
2100
2101        @Override
2102        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2103            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2104                    != PackageManager.PERMISSION_GRANTED) {
2105                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2106                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2107                        + " without permission " + android.Manifest.permission.DUMP);
2108                return;
2109            }
2110
2111            synchronized (mActivityManagerService.mProcessCpuThread) {
2112                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2113                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2114                        SystemClock.uptimeMillis()));
2115            }
2116        }
2117    }
2118
2119    public static final class Lifecycle extends SystemService {
2120        private final ActivityManagerService mService;
2121
2122        public Lifecycle(Context context) {
2123            super(context);
2124            mService = new ActivityManagerService(context);
2125        }
2126
2127        @Override
2128        public void onStart() {
2129            mService.start();
2130        }
2131
2132        public ActivityManagerService getService() {
2133            return mService;
2134        }
2135    }
2136
2137    // Note: This method is invoked on the main thread but may need to attach various
2138    // handlers to other threads.  So take care to be explicit about the looper.
2139    public ActivityManagerService(Context systemContext) {
2140        mContext = systemContext;
2141        mFactoryTest = FactoryTest.getMode();
2142        mSystemThread = ActivityThread.currentActivityThread();
2143
2144        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2145
2146        mHandlerThread = new ServiceThread(TAG,
2147                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2148        mHandlerThread.start();
2149        mHandler = new MainHandler(mHandlerThread.getLooper());
2150
2151        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2152                "foreground", BROADCAST_FG_TIMEOUT, false);
2153        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2154                "background", BROADCAST_BG_TIMEOUT, true);
2155        mBroadcastQueues[0] = mFgBroadcastQueue;
2156        mBroadcastQueues[1] = mBgBroadcastQueue;
2157
2158        mServices = new ActiveServices(this);
2159        mProviderMap = new ProviderMap(this);
2160
2161        // TODO: Move creation of battery stats service outside of activity manager service.
2162        File dataDir = Environment.getDataDirectory();
2163        File systemDir = new File(dataDir, "system");
2164        systemDir.mkdirs();
2165        mBatteryStatsService = new BatteryStatsService(new File(
2166                systemDir, "batterystats.bin").toString(), mHandler);
2167        mBatteryStatsService.getActiveStatistics().readLocked();
2168        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2169        mOnBattery = DEBUG_POWER ? true
2170                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2171        mBatteryStatsService.getActiveStatistics().setCallback(this);
2172
2173        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2174
2175        mUsageStatsService = new UsageStatsService(new File(systemDir, "usagestats").toString());
2176        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2177
2178        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2179
2180        // User 0 is the first and only user that runs at boot.
2181        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2182        mUserLru.add(Integer.valueOf(0));
2183        updateStartedUserArrayLocked();
2184
2185        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2186            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2187
2188        mConfiguration.setToDefaults();
2189        mConfiguration.setLocale(Locale.getDefault());
2190
2191        mConfigurationSeq = mConfiguration.seq = 1;
2192        mProcessCpuTracker.init();
2193
2194        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2195        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2196        mStackSupervisor = new ActivityStackSupervisor(this);
2197        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2198
2199        mProcessCpuThread = new Thread("CpuTracker") {
2200            @Override
2201            public void run() {
2202                while (true) {
2203                    try {
2204                        try {
2205                            synchronized(this) {
2206                                final long now = SystemClock.uptimeMillis();
2207                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2208                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2209                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2210                                //        + ", write delay=" + nextWriteDelay);
2211                                if (nextWriteDelay < nextCpuDelay) {
2212                                    nextCpuDelay = nextWriteDelay;
2213                                }
2214                                if (nextCpuDelay > 0) {
2215                                    mProcessCpuMutexFree.set(true);
2216                                    this.wait(nextCpuDelay);
2217                                }
2218                            }
2219                        } catch (InterruptedException e) {
2220                        }
2221                        updateCpuStatsNow();
2222                    } catch (Exception e) {
2223                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2224                    }
2225                }
2226            }
2227        };
2228
2229        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2230
2231        Watchdog.getInstance().addMonitor(this);
2232        Watchdog.getInstance().addThread(mHandler);
2233    }
2234
2235    public void setSystemServiceManager(SystemServiceManager mgr) {
2236        mSystemServiceManager = mgr;
2237    }
2238
2239    private void start() {
2240        mProcessCpuThread.start();
2241
2242        mBatteryStatsService.publish(mContext);
2243        mUsageStatsService.publish(mContext);
2244        mAppOpsService.publish(mContext);
2245        Slog.d("AppOps", "AppOpsService published");
2246        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2247    }
2248
2249    public void initPowerManagement() {
2250        mStackSupervisor.initPowerManagement();
2251        mBatteryStatsService.initPowerManagement();
2252    }
2253
2254    @Override
2255    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2256            throws RemoteException {
2257        if (code == SYSPROPS_TRANSACTION) {
2258            // We need to tell all apps about the system property change.
2259            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2260            synchronized(this) {
2261                final int NP = mProcessNames.getMap().size();
2262                for (int ip=0; ip<NP; ip++) {
2263                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2264                    final int NA = apps.size();
2265                    for (int ia=0; ia<NA; ia++) {
2266                        ProcessRecord app = apps.valueAt(ia);
2267                        if (app.thread != null) {
2268                            procs.add(app.thread.asBinder());
2269                        }
2270                    }
2271                }
2272            }
2273
2274            int N = procs.size();
2275            for (int i=0; i<N; i++) {
2276                Parcel data2 = Parcel.obtain();
2277                try {
2278                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2279                } catch (RemoteException e) {
2280                }
2281                data2.recycle();
2282            }
2283        }
2284        try {
2285            return super.onTransact(code, data, reply, flags);
2286        } catch (RuntimeException e) {
2287            // The activity manager only throws security exceptions, so let's
2288            // log all others.
2289            if (!(e instanceof SecurityException)) {
2290                Slog.wtf(TAG, "Activity Manager Crash", e);
2291            }
2292            throw e;
2293        }
2294    }
2295
2296    void updateCpuStats() {
2297        final long now = SystemClock.uptimeMillis();
2298        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2299            return;
2300        }
2301        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2302            synchronized (mProcessCpuThread) {
2303                mProcessCpuThread.notify();
2304            }
2305        }
2306    }
2307
2308    void updateCpuStatsNow() {
2309        synchronized (mProcessCpuThread) {
2310            mProcessCpuMutexFree.set(false);
2311            final long now = SystemClock.uptimeMillis();
2312            boolean haveNewCpuStats = false;
2313
2314            if (MONITOR_CPU_USAGE &&
2315                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2316                mLastCpuTime.set(now);
2317                haveNewCpuStats = true;
2318                mProcessCpuTracker.update();
2319                //Slog.i(TAG, mProcessCpu.printCurrentState());
2320                //Slog.i(TAG, "Total CPU usage: "
2321                //        + mProcessCpu.getTotalCpuPercent() + "%");
2322
2323                // Slog the cpu usage if the property is set.
2324                if ("true".equals(SystemProperties.get("events.cpu"))) {
2325                    int user = mProcessCpuTracker.getLastUserTime();
2326                    int system = mProcessCpuTracker.getLastSystemTime();
2327                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2328                    int irq = mProcessCpuTracker.getLastIrqTime();
2329                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2330                    int idle = mProcessCpuTracker.getLastIdleTime();
2331
2332                    int total = user + system + iowait + irq + softIrq + idle;
2333                    if (total == 0) total = 1;
2334
2335                    EventLog.writeEvent(EventLogTags.CPU,
2336                            ((user+system+iowait+irq+softIrq) * 100) / total,
2337                            (user * 100) / total,
2338                            (system * 100) / total,
2339                            (iowait * 100) / total,
2340                            (irq * 100) / total,
2341                            (softIrq * 100) / total);
2342                }
2343            }
2344
2345            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2346            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2347            synchronized(bstats) {
2348                synchronized(mPidsSelfLocked) {
2349                    if (haveNewCpuStats) {
2350                        if (mOnBattery) {
2351                            int perc = bstats.startAddingCpuLocked();
2352                            int totalUTime = 0;
2353                            int totalSTime = 0;
2354                            final int N = mProcessCpuTracker.countStats();
2355                            for (int i=0; i<N; i++) {
2356                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2357                                if (!st.working) {
2358                                    continue;
2359                                }
2360                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2361                                int otherUTime = (st.rel_utime*perc)/100;
2362                                int otherSTime = (st.rel_stime*perc)/100;
2363                                totalUTime += otherUTime;
2364                                totalSTime += otherSTime;
2365                                if (pr != null) {
2366                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2367                                    if (ps == null || !ps.isActive()) {
2368                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2369                                                pr.info.uid, pr.processName);
2370                                    }
2371                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2372                                            st.rel_stime-otherSTime);
2373                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2374                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2375                                } else {
2376                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2377                                    if (ps == null || !ps.isActive()) {
2378                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2379                                                bstats.mapUid(st.uid), st.name);
2380                                    }
2381                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2382                                            st.rel_stime-otherSTime);
2383                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2384                                }
2385                            }
2386                            bstats.finishAddingCpuLocked(perc, totalUTime,
2387                                    totalSTime, cpuSpeedTimes);
2388                        }
2389                    }
2390                }
2391
2392                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2393                    mLastWriteTime = now;
2394                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2395                }
2396            }
2397        }
2398    }
2399
2400    @Override
2401    public void batteryNeedsCpuUpdate() {
2402        updateCpuStatsNow();
2403    }
2404
2405    @Override
2406    public void batteryPowerChanged(boolean onBattery) {
2407        // When plugging in, update the CPU stats first before changing
2408        // the plug state.
2409        updateCpuStatsNow();
2410        synchronized (this) {
2411            synchronized(mPidsSelfLocked) {
2412                mOnBattery = DEBUG_POWER ? true : onBattery;
2413            }
2414        }
2415    }
2416
2417    /**
2418     * Initialize the application bind args. These are passed to each
2419     * process when the bindApplication() IPC is sent to the process. They're
2420     * lazily setup to make sure the services are running when they're asked for.
2421     */
2422    private HashMap<String, IBinder> getCommonServicesLocked() {
2423        if (mAppBindArgs == null) {
2424            mAppBindArgs = new HashMap<String, IBinder>();
2425
2426            // Setup the application init args
2427            mAppBindArgs.put("package", ServiceManager.getService("package"));
2428            mAppBindArgs.put("window", ServiceManager.getService("window"));
2429            mAppBindArgs.put(Context.ALARM_SERVICE,
2430                    ServiceManager.getService(Context.ALARM_SERVICE));
2431        }
2432        return mAppBindArgs;
2433    }
2434
2435    final void setFocusedActivityLocked(ActivityRecord r) {
2436        if (mFocusedActivity != r) {
2437            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2438            mFocusedActivity = r;
2439            if (r.task != null && r.task.voiceInteractor != null) {
2440                startRunningVoiceLocked();
2441            } else {
2442                finishRunningVoiceLocked();
2443            }
2444            mStackSupervisor.setFocusedStack(r);
2445            if (r != null) {
2446                mWindowManager.setFocusedApp(r.appToken, true);
2447            }
2448            applyUpdateLockStateLocked(r);
2449        }
2450    }
2451
2452    final void clearFocusedActivity(ActivityRecord r) {
2453        if (mFocusedActivity == r) {
2454            mFocusedActivity = null;
2455        }
2456    }
2457
2458    @Override
2459    public void setFocusedStack(int stackId) {
2460        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2461        synchronized (ActivityManagerService.this) {
2462            ActivityStack stack = mStackSupervisor.getStack(stackId);
2463            if (stack != null) {
2464                ActivityRecord r = stack.topRunningActivityLocked(null);
2465                if (r != null) {
2466                    setFocusedActivityLocked(r);
2467                }
2468            }
2469        }
2470    }
2471
2472    @Override
2473    public void notifyActivityDrawn(IBinder token) {
2474        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2475        synchronized (this) {
2476            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2477            if (r != null) {
2478                r.task.stack.notifyActivityDrawnLocked(r);
2479            }
2480        }
2481    }
2482
2483    final void applyUpdateLockStateLocked(ActivityRecord r) {
2484        // Modifications to the UpdateLock state are done on our handler, outside
2485        // the activity manager's locks.  The new state is determined based on the
2486        // state *now* of the relevant activity record.  The object is passed to
2487        // the handler solely for logging detail, not to be consulted/modified.
2488        final boolean nextState = r != null && r.immersive;
2489        mHandler.sendMessage(
2490                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2491    }
2492
2493    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2494        Message msg = Message.obtain();
2495        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2496        msg.obj = r.task.askedCompatMode ? null : r;
2497        mHandler.sendMessage(msg);
2498    }
2499
2500    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2501            String what, Object obj, ProcessRecord srcApp) {
2502        app.lastActivityTime = now;
2503
2504        if (app.activities.size() > 0) {
2505            // Don't want to touch dependent processes that are hosting activities.
2506            return index;
2507        }
2508
2509        int lrui = mLruProcesses.lastIndexOf(app);
2510        if (lrui < 0) {
2511            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2512                    + what + " " + obj + " from " + srcApp);
2513            return index;
2514        }
2515
2516        if (lrui >= index) {
2517            // Don't want to cause this to move dependent processes *back* in the
2518            // list as if they were less frequently used.
2519            return index;
2520        }
2521
2522        if (lrui >= mLruProcessActivityStart) {
2523            // Don't want to touch dependent processes that are hosting activities.
2524            return index;
2525        }
2526
2527        mLruProcesses.remove(lrui);
2528        if (index > 0) {
2529            index--;
2530        }
2531        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2532                + " in LRU list: " + app);
2533        mLruProcesses.add(index, app);
2534        return index;
2535    }
2536
2537    final void removeLruProcessLocked(ProcessRecord app) {
2538        int lrui = mLruProcesses.lastIndexOf(app);
2539        if (lrui >= 0) {
2540            if (lrui <= mLruProcessActivityStart) {
2541                mLruProcessActivityStart--;
2542            }
2543            if (lrui <= mLruProcessServiceStart) {
2544                mLruProcessServiceStart--;
2545            }
2546            mLruProcesses.remove(lrui);
2547        }
2548    }
2549
2550    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2551            ProcessRecord client) {
2552        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2553                || app.treatLikeActivity;
2554        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2555        if (!activityChange && hasActivity) {
2556            // The process has activities, so we are only allowing activity-based adjustments
2557            // to move it.  It should be kept in the front of the list with other
2558            // processes that have activities, and we don't want those to change their
2559            // order except due to activity operations.
2560            return;
2561        }
2562
2563        mLruSeq++;
2564        final long now = SystemClock.uptimeMillis();
2565        app.lastActivityTime = now;
2566
2567        // First a quick reject: if the app is already at the position we will
2568        // put it, then there is nothing to do.
2569        if (hasActivity) {
2570            final int N = mLruProcesses.size();
2571            if (N > 0 && mLruProcesses.get(N-1) == app) {
2572                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2573                return;
2574            }
2575        } else {
2576            if (mLruProcessServiceStart > 0
2577                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2578                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2579                return;
2580            }
2581        }
2582
2583        int lrui = mLruProcesses.lastIndexOf(app);
2584
2585        if (app.persistent && lrui >= 0) {
2586            // We don't care about the position of persistent processes, as long as
2587            // they are in the list.
2588            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2589            return;
2590        }
2591
2592        /* In progress: compute new position first, so we can avoid doing work
2593           if the process is not actually going to move.  Not yet working.
2594        int addIndex;
2595        int nextIndex;
2596        boolean inActivity = false, inService = false;
2597        if (hasActivity) {
2598            // Process has activities, put it at the very tipsy-top.
2599            addIndex = mLruProcesses.size();
2600            nextIndex = mLruProcessServiceStart;
2601            inActivity = true;
2602        } else if (hasService) {
2603            // Process has services, put it at the top of the service list.
2604            addIndex = mLruProcessActivityStart;
2605            nextIndex = mLruProcessServiceStart;
2606            inActivity = true;
2607            inService = true;
2608        } else  {
2609            // Process not otherwise of interest, it goes to the top of the non-service area.
2610            addIndex = mLruProcessServiceStart;
2611            if (client != null) {
2612                int clientIndex = mLruProcesses.lastIndexOf(client);
2613                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2614                        + app);
2615                if (clientIndex >= 0 && addIndex > clientIndex) {
2616                    addIndex = clientIndex;
2617                }
2618            }
2619            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2620        }
2621
2622        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2623                + mLruProcessActivityStart + "): " + app);
2624        */
2625
2626        if (lrui >= 0) {
2627            if (lrui < mLruProcessActivityStart) {
2628                mLruProcessActivityStart--;
2629            }
2630            if (lrui < mLruProcessServiceStart) {
2631                mLruProcessServiceStart--;
2632            }
2633            /*
2634            if (addIndex > lrui) {
2635                addIndex--;
2636            }
2637            if (nextIndex > lrui) {
2638                nextIndex--;
2639            }
2640            */
2641            mLruProcesses.remove(lrui);
2642        }
2643
2644        /*
2645        mLruProcesses.add(addIndex, app);
2646        if (inActivity) {
2647            mLruProcessActivityStart++;
2648        }
2649        if (inService) {
2650            mLruProcessActivityStart++;
2651        }
2652        */
2653
2654        int nextIndex;
2655        if (hasActivity) {
2656            final int N = mLruProcesses.size();
2657            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2658                // Process doesn't have activities, but has clients with
2659                // activities...  move it up, but one below the top (the top
2660                // should always have a real activity).
2661                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2662                mLruProcesses.add(N-1, app);
2663                // To keep it from spamming the LRU list (by making a bunch of clients),
2664                // we will push down any other entries owned by the app.
2665                final int uid = app.info.uid;
2666                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2667                    ProcessRecord subProc = mLruProcesses.get(i);
2668                    if (subProc.info.uid == uid) {
2669                        // We want to push this one down the list.  If the process after
2670                        // it is for the same uid, however, don't do so, because we don't
2671                        // want them internally to be re-ordered.
2672                        if (mLruProcesses.get(i-1).info.uid != uid) {
2673                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2674                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2675                            ProcessRecord tmp = mLruProcesses.get(i);
2676                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2677                            mLruProcesses.set(i-1, tmp);
2678                            i--;
2679                        }
2680                    } else {
2681                        // A gap, we can stop here.
2682                        break;
2683                    }
2684                }
2685            } else {
2686                // Process has activities, put it at the very tipsy-top.
2687                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2688                mLruProcesses.add(app);
2689            }
2690            nextIndex = mLruProcessServiceStart;
2691        } else if (hasService) {
2692            // Process has services, put it at the top of the service list.
2693            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2694            mLruProcesses.add(mLruProcessActivityStart, app);
2695            nextIndex = mLruProcessServiceStart;
2696            mLruProcessActivityStart++;
2697        } else  {
2698            // Process not otherwise of interest, it goes to the top of the non-service area.
2699            int index = mLruProcessServiceStart;
2700            if (client != null) {
2701                // If there is a client, don't allow the process to be moved up higher
2702                // in the list than that client.
2703                int clientIndex = mLruProcesses.lastIndexOf(client);
2704                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2705                        + " when updating " + app);
2706                if (clientIndex <= lrui) {
2707                    // Don't allow the client index restriction to push it down farther in the
2708                    // list than it already is.
2709                    clientIndex = lrui;
2710                }
2711                if (clientIndex >= 0 && index > clientIndex) {
2712                    index = clientIndex;
2713                }
2714            }
2715            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2716            mLruProcesses.add(index, app);
2717            nextIndex = index-1;
2718            mLruProcessActivityStart++;
2719            mLruProcessServiceStart++;
2720        }
2721
2722        // If the app is currently using a content provider or service,
2723        // bump those processes as well.
2724        for (int j=app.connections.size()-1; j>=0; j--) {
2725            ConnectionRecord cr = app.connections.valueAt(j);
2726            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2727                    && cr.binding.service.app != null
2728                    && cr.binding.service.app.lruSeq != mLruSeq
2729                    && !cr.binding.service.app.persistent) {
2730                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2731                        "service connection", cr, app);
2732            }
2733        }
2734        for (int j=app.conProviders.size()-1; j>=0; j--) {
2735            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2736            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2737                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2738                        "provider reference", cpr, app);
2739            }
2740        }
2741    }
2742
2743    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2744        if (uid == Process.SYSTEM_UID) {
2745            // The system gets to run in any process.  If there are multiple
2746            // processes with the same uid, just pick the first (this
2747            // should never happen).
2748            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2749            if (procs == null) return null;
2750            final int N = procs.size();
2751            for (int i = 0; i < N; i++) {
2752                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2753            }
2754        }
2755        ProcessRecord proc = mProcessNames.get(processName, uid);
2756        if (false && proc != null && !keepIfLarge
2757                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2758                && proc.lastCachedPss >= 4000) {
2759            // Turn this condition on to cause killing to happen regularly, for testing.
2760            if (proc.baseProcessTracker != null) {
2761                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2762            }
2763            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2764                    + "k from cached");
2765        } else if (proc != null && !keepIfLarge
2766                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2767                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2768            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2769            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2770                if (proc.baseProcessTracker != null) {
2771                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2772                }
2773                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2774                        + "k from cached");
2775            }
2776        }
2777        return proc;
2778    }
2779
2780    void ensurePackageDexOpt(String packageName) {
2781        IPackageManager pm = AppGlobals.getPackageManager();
2782        try {
2783            if (pm.performDexOpt(packageName)) {
2784                mDidDexOpt = true;
2785            }
2786        } catch (RemoteException e) {
2787        }
2788    }
2789
2790    boolean isNextTransitionForward() {
2791        int transit = mWindowManager.getPendingAppTransition();
2792        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2793                || transit == AppTransition.TRANSIT_TASK_OPEN
2794                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2795    }
2796
2797    final ProcessRecord startProcessLocked(String processName,
2798            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2799            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2800            boolean isolated, boolean keepIfLarge) {
2801        ProcessRecord app;
2802        if (!isolated) {
2803            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2804        } else {
2805            // If this is an isolated process, it can't re-use an existing process.
2806            app = null;
2807        }
2808        // We don't have to do anything more if:
2809        // (1) There is an existing application record; and
2810        // (2) The caller doesn't think it is dead, OR there is no thread
2811        //     object attached to it so we know it couldn't have crashed; and
2812        // (3) There is a pid assigned to it, so it is either starting or
2813        //     already running.
2814        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2815                + " app=" + app + " knownToBeDead=" + knownToBeDead
2816                + " thread=" + (app != null ? app.thread : null)
2817                + " pid=" + (app != null ? app.pid : -1));
2818        if (app != null && app.pid > 0) {
2819            if (!knownToBeDead || app.thread == null) {
2820                // We already have the app running, or are waiting for it to
2821                // come up (we have a pid but not yet its thread), so keep it.
2822                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2823                // If this is a new package in the process, add the package to the list
2824                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2825                return app;
2826            }
2827
2828            // An application record is attached to a previous process,
2829            // clean it up now.
2830            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2831            handleAppDiedLocked(app, true, true);
2832        }
2833
2834        String hostingNameStr = hostingName != null
2835                ? hostingName.flattenToShortString() : null;
2836
2837        if (!isolated) {
2838            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2839                // If we are in the background, then check to see if this process
2840                // is bad.  If so, we will just silently fail.
2841                if (mBadProcesses.get(info.processName, info.uid) != null) {
2842                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2843                            + "/" + info.processName);
2844                    return null;
2845                }
2846            } else {
2847                // When the user is explicitly starting a process, then clear its
2848                // crash count so that we won't make it bad until they see at
2849                // least one crash dialog again, and make the process good again
2850                // if it had been bad.
2851                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2852                        + "/" + info.processName);
2853                mProcessCrashTimes.remove(info.processName, info.uid);
2854                if (mBadProcesses.get(info.processName, info.uid) != null) {
2855                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2856                            UserHandle.getUserId(info.uid), info.uid,
2857                            info.processName);
2858                    mBadProcesses.remove(info.processName, info.uid);
2859                    if (app != null) {
2860                        app.bad = false;
2861                    }
2862                }
2863            }
2864        }
2865
2866        if (app == null) {
2867            app = newProcessRecordLocked(info, processName, isolated);
2868            if (app == null) {
2869                Slog.w(TAG, "Failed making new process record for "
2870                        + processName + "/" + info.uid + " isolated=" + isolated);
2871                return null;
2872            }
2873            mProcessNames.put(processName, app.uid, app);
2874            if (isolated) {
2875                mIsolatedProcesses.put(app.uid, app);
2876            }
2877        } else {
2878            // If this is a new package in the process, add the package to the list
2879            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2880        }
2881
2882        // If the system is not ready yet, then hold off on starting this
2883        // process until it is.
2884        if (!mProcessesReady
2885                && !isAllowedWhileBooting(info)
2886                && !allowWhileBooting) {
2887            if (!mProcessesOnHold.contains(app)) {
2888                mProcessesOnHold.add(app);
2889            }
2890            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2891            return app;
2892        }
2893
2894        startProcessLocked(app, hostingType, hostingNameStr, null /* ABI override */);
2895        return (app.pid != 0) ? app : null;
2896    }
2897
2898    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2899        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2900    }
2901
2902    private final void startProcessLocked(ProcessRecord app,
2903            String hostingType, String hostingNameStr, String abiOverride) {
2904        if (app.pid > 0 && app.pid != MY_PID) {
2905            synchronized (mPidsSelfLocked) {
2906                mPidsSelfLocked.remove(app.pid);
2907                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2908            }
2909            app.setPid(0);
2910        }
2911
2912        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2913                "startProcessLocked removing on hold: " + app);
2914        mProcessesOnHold.remove(app);
2915
2916        updateCpuStats();
2917
2918        try {
2919            int uid = app.uid;
2920
2921            int[] gids = null;
2922            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2923            if (!app.isolated) {
2924                int[] permGids = null;
2925                try {
2926                    final PackageManager pm = mContext.getPackageManager();
2927                    permGids = pm.getPackageGids(app.info.packageName);
2928
2929                    if (Environment.isExternalStorageEmulated()) {
2930                        if (pm.checkPermission(
2931                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2932                                app.info.packageName) == PERMISSION_GRANTED) {
2933                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2934                        } else {
2935                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2936                        }
2937                    }
2938                } catch (PackageManager.NameNotFoundException e) {
2939                    Slog.w(TAG, "Unable to retrieve gids", e);
2940                }
2941
2942                /*
2943                 * Add shared application and profile GIDs so applications can share some
2944                 * resources like shared libraries and access user-wide resources
2945                 */
2946                if (permGids == null) {
2947                    gids = new int[2];
2948                } else {
2949                    gids = new int[permGids.length + 2];
2950                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
2951                }
2952                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
2953                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
2954            }
2955            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
2956                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
2957                        && mTopComponent != null
2958                        && app.processName.equals(mTopComponent.getPackageName())) {
2959                    uid = 0;
2960                }
2961                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
2962                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2963                    uid = 0;
2964                }
2965            }
2966            int debugFlags = 0;
2967            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2968                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
2969                // Also turn on CheckJNI for debuggable apps. It's quite
2970                // awkward to turn on otherwise.
2971                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2972            }
2973            // Run the app in safe mode if its manifest requests so or the
2974            // system is booted in safe mode.
2975            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2976                mSafeMode == true) {
2977                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2978            }
2979            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2980                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2981            }
2982            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2983                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2984            }
2985            if ("1".equals(SystemProperties.get("debug.assert"))) {
2986                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2987            }
2988
2989            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.cpuAbi;
2990            if (requiredAbi == null) {
2991                requiredAbi = Build.SUPPORTED_ABIS[0];
2992            }
2993
2994            // Start the process.  It will either succeed and return a result containing
2995            // the PID of the new process, or else throw a RuntimeException.
2996            Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
2997                    app.processName, uid, uid, gids, debugFlags, mountExternal,
2998                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
2999
3000            BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
3001            synchronized (bs) {
3002                if (bs.isOnBattery()) {
3003                    bs.getProcessStatsLocked(app.uid, app.processName).incStartsLocked();
3004                }
3005            }
3006
3007            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3008                    UserHandle.getUserId(uid), startResult.pid, uid,
3009                    app.processName, hostingType,
3010                    hostingNameStr != null ? hostingNameStr : "");
3011
3012            if (app.persistent) {
3013                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3014            }
3015
3016            StringBuilder buf = mStringBuilder;
3017            buf.setLength(0);
3018            buf.append("Start proc ");
3019            buf.append(app.processName);
3020            buf.append(" for ");
3021            buf.append(hostingType);
3022            if (hostingNameStr != null) {
3023                buf.append(" ");
3024                buf.append(hostingNameStr);
3025            }
3026            buf.append(": pid=");
3027            buf.append(startResult.pid);
3028            buf.append(" uid=");
3029            buf.append(uid);
3030            buf.append(" gids={");
3031            if (gids != null) {
3032                for (int gi=0; gi<gids.length; gi++) {
3033                    if (gi != 0) buf.append(", ");
3034                    buf.append(gids[gi]);
3035
3036                }
3037            }
3038            buf.append("}");
3039            if (requiredAbi != null) {
3040                buf.append(" abi=");
3041                buf.append(requiredAbi);
3042            }
3043            Slog.i(TAG, buf.toString());
3044            app.setPid(startResult.pid);
3045            app.usingWrapper = startResult.usingWrapper;
3046            app.removed = false;
3047            app.killedByAm = false;
3048            synchronized (mPidsSelfLocked) {
3049                this.mPidsSelfLocked.put(startResult.pid, app);
3050                Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3051                msg.obj = app;
3052                mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3053                        ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3054            }
3055            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_START,
3056                    app.processName, app.info.uid);
3057            if (app.isolated) {
3058                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3059            }
3060        } catch (RuntimeException e) {
3061            // XXX do better error recovery.
3062            app.setPid(0);
3063            Slog.e(TAG, "Failure starting process " + app.processName, e);
3064        }
3065    }
3066
3067    void updateUsageStats(ActivityRecord component, boolean resumed) {
3068        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3069        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3070        if (resumed) {
3071            mUsageStatsService.noteResumeComponent(component.realActivity);
3072            synchronized (stats) {
3073                stats.noteActivityResumedLocked(component.app.uid);
3074            }
3075        } else {
3076            mUsageStatsService.notePauseComponent(component.realActivity);
3077            synchronized (stats) {
3078                stats.noteActivityPausedLocked(component.app.uid);
3079            }
3080        }
3081    }
3082
3083    Intent getHomeIntent() {
3084        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3085        intent.setComponent(mTopComponent);
3086        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3087            intent.addCategory(Intent.CATEGORY_HOME);
3088        }
3089        return intent;
3090    }
3091
3092    boolean startHomeActivityLocked(int userId) {
3093        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3094                && mTopAction == null) {
3095            // We are running in factory test mode, but unable to find
3096            // the factory test app, so just sit around displaying the
3097            // error message and don't try to start anything.
3098            return false;
3099        }
3100        Intent intent = getHomeIntent();
3101        ActivityInfo aInfo =
3102            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3103        if (aInfo != null) {
3104            intent.setComponent(new ComponentName(
3105                    aInfo.applicationInfo.packageName, aInfo.name));
3106            // Don't do this if the home app is currently being
3107            // instrumented.
3108            aInfo = new ActivityInfo(aInfo);
3109            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3110            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3111                    aInfo.applicationInfo.uid, true);
3112            if (app == null || app.instrumentationClass == null) {
3113                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3114                mStackSupervisor.startHomeActivity(intent, aInfo);
3115            }
3116        }
3117
3118        return true;
3119    }
3120
3121    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3122        ActivityInfo ai = null;
3123        ComponentName comp = intent.getComponent();
3124        try {
3125            if (comp != null) {
3126                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3127            } else {
3128                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3129                        intent,
3130                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3131                            flags, userId);
3132
3133                if (info != null) {
3134                    ai = info.activityInfo;
3135                }
3136            }
3137        } catch (RemoteException e) {
3138            // ignore
3139        }
3140
3141        return ai;
3142    }
3143
3144    /**
3145     * Starts the "new version setup screen" if appropriate.
3146     */
3147    void startSetupActivityLocked() {
3148        // Only do this once per boot.
3149        if (mCheckedForSetup) {
3150            return;
3151        }
3152
3153        // We will show this screen if the current one is a different
3154        // version than the last one shown, and we are not running in
3155        // low-level factory test mode.
3156        final ContentResolver resolver = mContext.getContentResolver();
3157        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3158                Settings.Global.getInt(resolver,
3159                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3160            mCheckedForSetup = true;
3161
3162            // See if we should be showing the platform update setup UI.
3163            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3164            List<ResolveInfo> ris = mContext.getPackageManager()
3165                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3166
3167            // We don't allow third party apps to replace this.
3168            ResolveInfo ri = null;
3169            for (int i=0; ris != null && i<ris.size(); i++) {
3170                if ((ris.get(i).activityInfo.applicationInfo.flags
3171                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3172                    ri = ris.get(i);
3173                    break;
3174                }
3175            }
3176
3177            if (ri != null) {
3178                String vers = ri.activityInfo.metaData != null
3179                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3180                        : null;
3181                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3182                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3183                            Intent.METADATA_SETUP_VERSION);
3184                }
3185                String lastVers = Settings.Secure.getString(
3186                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3187                if (vers != null && !vers.equals(lastVers)) {
3188                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3189                    intent.setComponent(new ComponentName(
3190                            ri.activityInfo.packageName, ri.activityInfo.name));
3191                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3192                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3193                }
3194            }
3195        }
3196    }
3197
3198    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3199        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3200    }
3201
3202    void enforceNotIsolatedCaller(String caller) {
3203        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3204            throw new SecurityException("Isolated process not allowed to call " + caller);
3205        }
3206    }
3207
3208    @Override
3209    public int getFrontActivityScreenCompatMode() {
3210        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3211        synchronized (this) {
3212            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3213        }
3214    }
3215
3216    @Override
3217    public void setFrontActivityScreenCompatMode(int mode) {
3218        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3219                "setFrontActivityScreenCompatMode");
3220        synchronized (this) {
3221            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3222        }
3223    }
3224
3225    @Override
3226    public int getPackageScreenCompatMode(String packageName) {
3227        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3228        synchronized (this) {
3229            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3230        }
3231    }
3232
3233    @Override
3234    public void setPackageScreenCompatMode(String packageName, int mode) {
3235        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3236                "setPackageScreenCompatMode");
3237        synchronized (this) {
3238            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3239        }
3240    }
3241
3242    @Override
3243    public boolean getPackageAskScreenCompat(String packageName) {
3244        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3245        synchronized (this) {
3246            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3247        }
3248    }
3249
3250    @Override
3251    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3252        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3253                "setPackageAskScreenCompat");
3254        synchronized (this) {
3255            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3256        }
3257    }
3258
3259    private void dispatchProcessesChanged() {
3260        int N;
3261        synchronized (this) {
3262            N = mPendingProcessChanges.size();
3263            if (mActiveProcessChanges.length < N) {
3264                mActiveProcessChanges = new ProcessChangeItem[N];
3265            }
3266            mPendingProcessChanges.toArray(mActiveProcessChanges);
3267            mAvailProcessChanges.addAll(mPendingProcessChanges);
3268            mPendingProcessChanges.clear();
3269            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3270        }
3271
3272        int i = mProcessObservers.beginBroadcast();
3273        while (i > 0) {
3274            i--;
3275            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3276            if (observer != null) {
3277                try {
3278                    for (int j=0; j<N; j++) {
3279                        ProcessChangeItem item = mActiveProcessChanges[j];
3280                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3281                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3282                                    + item.pid + " uid=" + item.uid + ": "
3283                                    + item.foregroundActivities);
3284                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3285                                    item.foregroundActivities);
3286                        }
3287                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3288                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3289                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3290                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3291                        }
3292                    }
3293                } catch (RemoteException e) {
3294                }
3295            }
3296        }
3297        mProcessObservers.finishBroadcast();
3298    }
3299
3300    private void dispatchProcessDied(int pid, int uid) {
3301        int i = mProcessObservers.beginBroadcast();
3302        while (i > 0) {
3303            i--;
3304            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3305            if (observer != null) {
3306                try {
3307                    observer.onProcessDied(pid, uid);
3308                } catch (RemoteException e) {
3309                }
3310            }
3311        }
3312        mProcessObservers.finishBroadcast();
3313    }
3314
3315    final void doPendingActivityLaunchesLocked(boolean doResume) {
3316        final int N = mPendingActivityLaunches.size();
3317        if (N <= 0) {
3318            return;
3319        }
3320        for (int i=0; i<N; i++) {
3321            PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
3322            mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, null, null, pal.startFlags,
3323                    doResume && i == (N-1), null);
3324        }
3325        mPendingActivityLaunches.clear();
3326    }
3327
3328    @Override
3329    public final int startActivity(IApplicationThread caller, String callingPackage,
3330            Intent intent, String resolvedType, IBinder resultTo,
3331            String resultWho, int requestCode, int startFlags,
3332            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3333        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3334                resultWho, requestCode,
3335                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3336    }
3337
3338    @Override
3339    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3340            Intent intent, String resolvedType, IBinder resultTo,
3341            String resultWho, int requestCode, int startFlags,
3342            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3343        enforceNotIsolatedCaller("startActivity");
3344        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3345                false, true, "startActivity", null);
3346        // TODO: Switch to user app stacks here.
3347        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3348                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3349                null, null, options, userId, null);
3350    }
3351
3352    @Override
3353    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3354            Intent intent, String resolvedType, IBinder resultTo,
3355            String resultWho, int requestCode, int startFlags, String profileFile,
3356            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3357        enforceNotIsolatedCaller("startActivityAndWait");
3358        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3359                false, true, "startActivityAndWait", null);
3360        WaitResult res = new WaitResult();
3361        // TODO: Switch to user app stacks here.
3362        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3363                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3364                res, null, options, UserHandle.getCallingUserId(), null);
3365        return res;
3366    }
3367
3368    @Override
3369    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3370            Intent intent, String resolvedType, IBinder resultTo,
3371            String resultWho, int requestCode, int startFlags, Configuration config,
3372            Bundle options, int userId) {
3373        enforceNotIsolatedCaller("startActivityWithConfig");
3374        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3375                false, true, "startActivityWithConfig", null);
3376        // TODO: Switch to user app stacks here.
3377        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3378                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3379                null, null, null, config, options, userId, null);
3380        return ret;
3381    }
3382
3383    @Override
3384    public int startActivityIntentSender(IApplicationThread caller,
3385            IntentSender intent, Intent fillInIntent, String resolvedType,
3386            IBinder resultTo, String resultWho, int requestCode,
3387            int flagsMask, int flagsValues, Bundle options) {
3388        enforceNotIsolatedCaller("startActivityIntentSender");
3389        // Refuse possible leaked file descriptors
3390        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3391            throw new IllegalArgumentException("File descriptors passed in Intent");
3392        }
3393
3394        IIntentSender sender = intent.getTarget();
3395        if (!(sender instanceof PendingIntentRecord)) {
3396            throw new IllegalArgumentException("Bad PendingIntent object");
3397        }
3398
3399        PendingIntentRecord pir = (PendingIntentRecord)sender;
3400
3401        synchronized (this) {
3402            // If this is coming from the currently resumed activity, it is
3403            // effectively saying that app switches are allowed at this point.
3404            final ActivityStack stack = getFocusedStack();
3405            if (stack.mResumedActivity != null &&
3406                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3407                mAppSwitchesAllowedTime = 0;
3408            }
3409        }
3410        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3411                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3412        return ret;
3413    }
3414
3415    @Override
3416    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3417            Intent intent, String resolvedType, IVoiceInteractionSession session,
3418            IVoiceInteractor interactor, int startFlags, String profileFile,
3419            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3420        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3421                != PackageManager.PERMISSION_GRANTED) {
3422            String msg = "Permission Denial: startVoiceActivity() from pid="
3423                    + Binder.getCallingPid()
3424                    + ", uid=" + Binder.getCallingUid()
3425                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3426            Slog.w(TAG, msg);
3427            throw new SecurityException(msg);
3428        }
3429        if (session == null || interactor == null) {
3430            throw new NullPointerException("null session or interactor");
3431        }
3432        userId = handleIncomingUser(callingPid, callingUid, userId,
3433                false, true, "startVoiceActivity", null);
3434        // TODO: Switch to user app stacks here.
3435        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3436                resolvedType, session, interactor, null, null, 0, startFlags,
3437                profileFile, profileFd, null, null, options, userId, null);
3438    }
3439
3440    @Override
3441    public boolean startNextMatchingActivity(IBinder callingActivity,
3442            Intent intent, Bundle options) {
3443        // Refuse possible leaked file descriptors
3444        if (intent != null && intent.hasFileDescriptors() == true) {
3445            throw new IllegalArgumentException("File descriptors passed in Intent");
3446        }
3447
3448        synchronized (this) {
3449            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3450            if (r == null) {
3451                ActivityOptions.abort(options);
3452                return false;
3453            }
3454            if (r.app == null || r.app.thread == null) {
3455                // The caller is not running...  d'oh!
3456                ActivityOptions.abort(options);
3457                return false;
3458            }
3459            intent = new Intent(intent);
3460            // The caller is not allowed to change the data.
3461            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3462            // And we are resetting to find the next component...
3463            intent.setComponent(null);
3464
3465            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3466
3467            ActivityInfo aInfo = null;
3468            try {
3469                List<ResolveInfo> resolves =
3470                    AppGlobals.getPackageManager().queryIntentActivities(
3471                            intent, r.resolvedType,
3472                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3473                            UserHandle.getCallingUserId());
3474
3475                // Look for the original activity in the list...
3476                final int N = resolves != null ? resolves.size() : 0;
3477                for (int i=0; i<N; i++) {
3478                    ResolveInfo rInfo = resolves.get(i);
3479                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3480                            && rInfo.activityInfo.name.equals(r.info.name)) {
3481                        // We found the current one...  the next matching is
3482                        // after it.
3483                        i++;
3484                        if (i<N) {
3485                            aInfo = resolves.get(i).activityInfo;
3486                        }
3487                        if (debug) {
3488                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3489                                    + "/" + r.info.name);
3490                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3491                                    + "/" + aInfo.name);
3492                        }
3493                        break;
3494                    }
3495                }
3496            } catch (RemoteException e) {
3497            }
3498
3499            if (aInfo == null) {
3500                // Nobody who is next!
3501                ActivityOptions.abort(options);
3502                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3503                return false;
3504            }
3505
3506            intent.setComponent(new ComponentName(
3507                    aInfo.applicationInfo.packageName, aInfo.name));
3508            intent.setFlags(intent.getFlags()&~(
3509                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3510                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3511                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3512                    Intent.FLAG_ACTIVITY_NEW_TASK));
3513
3514            // Okay now we need to start the new activity, replacing the
3515            // currently running activity.  This is a little tricky because
3516            // we want to start the new one as if the current one is finished,
3517            // but not finish the current one first so that there is no flicker.
3518            // And thus...
3519            final boolean wasFinishing = r.finishing;
3520            r.finishing = true;
3521
3522            // Propagate reply information over to the new activity.
3523            final ActivityRecord resultTo = r.resultTo;
3524            final String resultWho = r.resultWho;
3525            final int requestCode = r.requestCode;
3526            r.resultTo = null;
3527            if (resultTo != null) {
3528                resultTo.removeResultsLocked(r, resultWho, requestCode);
3529            }
3530
3531            final long origId = Binder.clearCallingIdentity();
3532            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3533                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3534                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3535                    options, false, null, null);
3536            Binder.restoreCallingIdentity(origId);
3537
3538            r.finishing = wasFinishing;
3539            if (res != ActivityManager.START_SUCCESS) {
3540                return false;
3541            }
3542            return true;
3543        }
3544    }
3545
3546    final int startActivityInPackage(int uid, String callingPackage,
3547            Intent intent, String resolvedType, IBinder resultTo,
3548            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3549                    IActivityContainer container) {
3550
3551        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3552                false, true, "startActivityInPackage", null);
3553
3554        // TODO: Switch to user app stacks here.
3555        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3556                null, null, resultTo, resultWho, requestCode, startFlags,
3557                null, null, null, null, options, userId, container);
3558        return ret;
3559    }
3560
3561    @Override
3562    public final int startActivities(IApplicationThread caller, String callingPackage,
3563            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3564            int userId) {
3565        enforceNotIsolatedCaller("startActivities");
3566        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3567                false, true, "startActivity", null);
3568        // TODO: Switch to user app stacks here.
3569        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3570                resolvedTypes, resultTo, options, userId);
3571        return ret;
3572    }
3573
3574    final int startActivitiesInPackage(int uid, String callingPackage,
3575            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3576            Bundle options, int userId) {
3577
3578        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3579                false, true, "startActivityInPackage", null);
3580        // TODO: Switch to user app stacks here.
3581        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3582                resultTo, options, userId);
3583        return ret;
3584    }
3585
3586    final void addRecentTaskLocked(TaskRecord task) {
3587        int N = mRecentTasks.size();
3588        // Quick case: check if the top-most recent task is the same.
3589        if (N > 0 && mRecentTasks.get(0) == task) {
3590            return;
3591        }
3592        // Another quick case: never add voice sessions.
3593        if (task.voiceSession != null) {
3594            return;
3595        }
3596        // Remove any existing entries that are the same kind of task.
3597        final Intent intent = task.intent;
3598        final boolean document = intent != null && intent.isDocument();
3599        final ComponentName comp = intent.getComponent();
3600
3601        int maxRecents = task.maxRecents - 1;
3602        for (int i=0; i<N; i++) {
3603            TaskRecord tr = mRecentTasks.get(i);
3604            if (task != tr) {
3605                if (task.userId != tr.userId) {
3606                    continue;
3607                }
3608                if (i > MAX_RECENT_BITMAPS) {
3609                    tr.freeLastThumbnail();
3610                }
3611                final Intent trIntent = tr.intent;
3612                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3613                    (intent == null || !intent.filterEquals(trIntent))) {
3614                    continue;
3615                }
3616                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3617                if (document && trIsDocument) {
3618                    // These are the same document activity (not necessarily the same doc).
3619                    if (maxRecents > 0) {
3620                        --maxRecents;
3621                        continue;
3622                    }
3623                    // Hit the maximum number of documents for this task. Fall through
3624                    // and remove this document from recents.
3625                } else if (document || trIsDocument) {
3626                    // Only one of these is a document. Not the droid we're looking for.
3627                    continue;
3628                }
3629            }
3630
3631            // Either task and tr are the same or, their affinities match or their intents match
3632            // and neither of them is a document, or they are documents using the same activity
3633            // and their maxRecents has been reached.
3634            tr.disposeThumbnail();
3635            mRecentTasks.remove(i);
3636            i--;
3637            N--;
3638            if (task.intent == null) {
3639                // If the new recent task we are adding is not fully
3640                // specified, then replace it with the existing recent task.
3641                task = tr;
3642            }
3643            mTaskPersister.notify(tr, false);
3644        }
3645        if (N >= MAX_RECENT_TASKS) {
3646            mRecentTasks.remove(N-1).disposeThumbnail();
3647        }
3648        mRecentTasks.add(0, task);
3649    }
3650
3651    @Override
3652    public void reportActivityFullyDrawn(IBinder token) {
3653        synchronized (this) {
3654            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3655            if (r == null) {
3656                return;
3657            }
3658            r.reportFullyDrawnLocked();
3659        }
3660    }
3661
3662    @Override
3663    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3664        synchronized (this) {
3665            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3666            if (r == null) {
3667                return;
3668            }
3669            final long origId = Binder.clearCallingIdentity();
3670            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3671            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3672                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3673            if (config != null) {
3674                r.frozenBeforeDestroy = true;
3675                if (!updateConfigurationLocked(config, r, false, false)) {
3676                    mStackSupervisor.resumeTopActivitiesLocked();
3677                }
3678            }
3679            Binder.restoreCallingIdentity(origId);
3680        }
3681    }
3682
3683    @Override
3684    public int getRequestedOrientation(IBinder token) {
3685        synchronized (this) {
3686            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3687            if (r == null) {
3688                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3689            }
3690            return mWindowManager.getAppOrientation(r.appToken);
3691        }
3692    }
3693
3694    /**
3695     * This is the internal entry point for handling Activity.finish().
3696     *
3697     * @param token The Binder token referencing the Activity we want to finish.
3698     * @param resultCode Result code, if any, from this Activity.
3699     * @param resultData Result data (Intent), if any, from this Activity.
3700     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3701     *            the root Activity in the task.
3702     *
3703     * @return Returns true if the activity successfully finished, or false if it is still running.
3704     */
3705    @Override
3706    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3707            boolean finishTask) {
3708        // Refuse possible leaked file descriptors
3709        if (resultData != null && resultData.hasFileDescriptors() == true) {
3710            throw new IllegalArgumentException("File descriptors passed in Intent");
3711        }
3712
3713        synchronized(this) {
3714            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3715            if (r == null) {
3716                return true;
3717            }
3718            // Keep track of the root activity of the task before we finish it
3719            TaskRecord tr = r.task;
3720            ActivityRecord rootR = tr.getRootActivity();
3721            // Do not allow task to finish in Lock Task mode.
3722            if (tr == mStackSupervisor.mLockTaskModeTask) {
3723                if (rootR == r) {
3724                    mStackSupervisor.showLockTaskToast();
3725                    return false;
3726                }
3727            }
3728            if (mController != null) {
3729                // Find the first activity that is not finishing.
3730                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3731                if (next != null) {
3732                    // ask watcher if this is allowed
3733                    boolean resumeOK = true;
3734                    try {
3735                        resumeOK = mController.activityResuming(next.packageName);
3736                    } catch (RemoteException e) {
3737                        mController = null;
3738                        Watchdog.getInstance().setActivityController(null);
3739                    }
3740
3741                    if (!resumeOK) {
3742                        return false;
3743                    }
3744                }
3745            }
3746            final long origId = Binder.clearCallingIdentity();
3747            try {
3748                boolean res;
3749                if (finishTask && r == rootR) {
3750                    // If requested, remove the task that is associated to this activity only if it
3751                    // was the root activity in the task.  The result code and data is ignored because
3752                    // we don't support returning them across task boundaries.
3753                    res = removeTaskByIdLocked(tr.taskId, 0);
3754                } else {
3755                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3756                            resultData, "app-request", true);
3757                }
3758                return res;
3759            } finally {
3760                Binder.restoreCallingIdentity(origId);
3761            }
3762        }
3763    }
3764
3765    @Override
3766    public final void finishHeavyWeightApp() {
3767        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3768                != PackageManager.PERMISSION_GRANTED) {
3769            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3770                    + Binder.getCallingPid()
3771                    + ", uid=" + Binder.getCallingUid()
3772                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3773            Slog.w(TAG, msg);
3774            throw new SecurityException(msg);
3775        }
3776
3777        synchronized(this) {
3778            if (mHeavyWeightProcess == null) {
3779                return;
3780            }
3781
3782            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3783                    mHeavyWeightProcess.activities);
3784            for (int i=0; i<activities.size(); i++) {
3785                ActivityRecord r = activities.get(i);
3786                if (!r.finishing) {
3787                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3788                            null, "finish-heavy", true);
3789                }
3790            }
3791
3792            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3793                    mHeavyWeightProcess.userId, 0));
3794            mHeavyWeightProcess = null;
3795        }
3796    }
3797
3798    @Override
3799    public void crashApplication(int uid, int initialPid, String packageName,
3800            String message) {
3801        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3802                != PackageManager.PERMISSION_GRANTED) {
3803            String msg = "Permission Denial: crashApplication() from pid="
3804                    + Binder.getCallingPid()
3805                    + ", uid=" + Binder.getCallingUid()
3806                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3807            Slog.w(TAG, msg);
3808            throw new SecurityException(msg);
3809        }
3810
3811        synchronized(this) {
3812            ProcessRecord proc = null;
3813
3814            // Figure out which process to kill.  We don't trust that initialPid
3815            // still has any relation to current pids, so must scan through the
3816            // list.
3817            synchronized (mPidsSelfLocked) {
3818                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3819                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3820                    if (p.uid != uid) {
3821                        continue;
3822                    }
3823                    if (p.pid == initialPid) {
3824                        proc = p;
3825                        break;
3826                    }
3827                    if (p.pkgList.containsKey(packageName)) {
3828                        proc = p;
3829                    }
3830                }
3831            }
3832
3833            if (proc == null) {
3834                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3835                        + " initialPid=" + initialPid
3836                        + " packageName=" + packageName);
3837                return;
3838            }
3839
3840            if (proc.thread != null) {
3841                if (proc.pid == Process.myPid()) {
3842                    Log.w(TAG, "crashApplication: trying to crash self!");
3843                    return;
3844                }
3845                long ident = Binder.clearCallingIdentity();
3846                try {
3847                    proc.thread.scheduleCrash(message);
3848                } catch (RemoteException e) {
3849                }
3850                Binder.restoreCallingIdentity(ident);
3851            }
3852        }
3853    }
3854
3855    @Override
3856    public final void finishSubActivity(IBinder token, String resultWho,
3857            int requestCode) {
3858        synchronized(this) {
3859            final long origId = Binder.clearCallingIdentity();
3860            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3861            if (r != null) {
3862                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3863            }
3864            Binder.restoreCallingIdentity(origId);
3865        }
3866    }
3867
3868    @Override
3869    public boolean finishActivityAffinity(IBinder token) {
3870        synchronized(this) {
3871            final long origId = Binder.clearCallingIdentity();
3872            try {
3873                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3874
3875                ActivityRecord rootR = r.task.getRootActivity();
3876                // Do not allow task to finish in Lock Task mode.
3877                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3878                    if (rootR == r) {
3879                        mStackSupervisor.showLockTaskToast();
3880                        return false;
3881                    }
3882                }
3883                boolean res = false;
3884                if (r != null) {
3885                    res = r.task.stack.finishActivityAffinityLocked(r);
3886                }
3887                return res;
3888            } finally {
3889                Binder.restoreCallingIdentity(origId);
3890            }
3891        }
3892    }
3893
3894    @Override
3895    public void finishVoiceTask(IVoiceInteractionSession session) {
3896        synchronized(this) {
3897            final long origId = Binder.clearCallingIdentity();
3898            try {
3899                mStackSupervisor.finishVoiceTask(session);
3900            } finally {
3901                Binder.restoreCallingIdentity(origId);
3902            }
3903        }
3904
3905    }
3906
3907    @Override
3908    public boolean willActivityBeVisible(IBinder token) {
3909        synchronized(this) {
3910            ActivityStack stack = ActivityRecord.getStackLocked(token);
3911            if (stack != null) {
3912                return stack.willActivityBeVisibleLocked(token);
3913            }
3914            return false;
3915        }
3916    }
3917
3918    @Override
3919    public void overridePendingTransition(IBinder token, String packageName,
3920            int enterAnim, int exitAnim) {
3921        synchronized(this) {
3922            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3923            if (self == null) {
3924                return;
3925            }
3926
3927            final long origId = Binder.clearCallingIdentity();
3928
3929            if (self.state == ActivityState.RESUMED
3930                    || self.state == ActivityState.PAUSING) {
3931                mWindowManager.overridePendingAppTransition(packageName,
3932                        enterAnim, exitAnim, null);
3933            }
3934
3935            Binder.restoreCallingIdentity(origId);
3936        }
3937    }
3938
3939    /**
3940     * Main function for removing an existing process from the activity manager
3941     * as a result of that process going away.  Clears out all connections
3942     * to the process.
3943     */
3944    private final void handleAppDiedLocked(ProcessRecord app,
3945            boolean restarting, boolean allowRestart) {
3946        int pid = app.pid;
3947        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3948        if (!restarting) {
3949            removeLruProcessLocked(app);
3950            if (pid > 0) {
3951                ProcessList.remove(pid);
3952            }
3953        }
3954
3955        if (mProfileProc == app) {
3956            clearProfilerLocked();
3957        }
3958
3959        // Remove this application's activities from active lists.
3960        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3961
3962        app.activities.clear();
3963
3964        if (app.instrumentationClass != null) {
3965            Slog.w(TAG, "Crash of app " + app.processName
3966                  + " running instrumentation " + app.instrumentationClass);
3967            Bundle info = new Bundle();
3968            info.putString("shortMsg", "Process crashed.");
3969            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3970        }
3971
3972        if (!restarting) {
3973            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3974                // If there was nothing to resume, and we are not already
3975                // restarting this process, but there is a visible activity that
3976                // is hosted by the process...  then make sure all visible
3977                // activities are running, taking care of restarting this
3978                // process.
3979                if (hasVisibleActivities) {
3980                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3981                }
3982            }
3983        }
3984    }
3985
3986    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3987        IBinder threadBinder = thread.asBinder();
3988        // Find the application record.
3989        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3990            ProcessRecord rec = mLruProcesses.get(i);
3991            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3992                return i;
3993            }
3994        }
3995        return -1;
3996    }
3997
3998    final ProcessRecord getRecordForAppLocked(
3999            IApplicationThread thread) {
4000        if (thread == null) {
4001            return null;
4002        }
4003
4004        int appIndex = getLRURecordIndexForAppLocked(thread);
4005        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4006    }
4007
4008    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4009        // If there are no longer any background processes running,
4010        // and the app that died was not running instrumentation,
4011        // then tell everyone we are now low on memory.
4012        boolean haveBg = false;
4013        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4014            ProcessRecord rec = mLruProcesses.get(i);
4015            if (rec.thread != null
4016                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4017                haveBg = true;
4018                break;
4019            }
4020        }
4021
4022        if (!haveBg) {
4023            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4024            if (doReport) {
4025                long now = SystemClock.uptimeMillis();
4026                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4027                    doReport = false;
4028                } else {
4029                    mLastMemUsageReportTime = now;
4030                }
4031            }
4032            final ArrayList<ProcessMemInfo> memInfos
4033                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4034            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4035            long now = SystemClock.uptimeMillis();
4036            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4037                ProcessRecord rec = mLruProcesses.get(i);
4038                if (rec == dyingProc || rec.thread == null) {
4039                    continue;
4040                }
4041                if (doReport) {
4042                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4043                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4044                }
4045                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4046                    // The low memory report is overriding any current
4047                    // state for a GC request.  Make sure to do
4048                    // heavy/important/visible/foreground processes first.
4049                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4050                        rec.lastRequestedGc = 0;
4051                    } else {
4052                        rec.lastRequestedGc = rec.lastLowMemory;
4053                    }
4054                    rec.reportLowMemory = true;
4055                    rec.lastLowMemory = now;
4056                    mProcessesToGc.remove(rec);
4057                    addProcessToGcListLocked(rec);
4058                }
4059            }
4060            if (doReport) {
4061                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4062                mHandler.sendMessage(msg);
4063            }
4064            scheduleAppGcsLocked();
4065        }
4066    }
4067
4068    final void appDiedLocked(ProcessRecord app, int pid,
4069            IApplicationThread thread) {
4070
4071        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4072        synchronized (stats) {
4073            stats.noteProcessDiedLocked(app.info.uid, pid);
4074        }
4075
4076        // Clean up already done if the process has been re-started.
4077        if (app.pid == pid && app.thread != null &&
4078                app.thread.asBinder() == thread.asBinder()) {
4079            boolean doLowMem = app.instrumentationClass == null;
4080            boolean doOomAdj = doLowMem;
4081            if (!app.killedByAm) {
4082                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4083                        + ") has died.");
4084                mAllowLowerMemLevel = true;
4085            } else {
4086                // Note that we always want to do oom adj to update our state with the
4087                // new number of procs.
4088                mAllowLowerMemLevel = false;
4089                doLowMem = false;
4090            }
4091            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4092            if (DEBUG_CLEANUP) Slog.v(
4093                TAG, "Dying app: " + app + ", pid: " + pid
4094                + ", thread: " + thread.asBinder());
4095            handleAppDiedLocked(app, false, true);
4096
4097            if (doOomAdj) {
4098                updateOomAdjLocked();
4099            }
4100            if (doLowMem) {
4101                doLowMemReportIfNeededLocked(app);
4102            }
4103        } else if (app.pid != pid) {
4104            // A new process has already been started.
4105            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4106                    + ") has died and restarted (pid " + app.pid + ").");
4107            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4108        } else if (DEBUG_PROCESSES) {
4109            Slog.d(TAG, "Received spurious death notification for thread "
4110                    + thread.asBinder());
4111        }
4112    }
4113
4114    /**
4115     * If a stack trace dump file is configured, dump process stack traces.
4116     * @param clearTraces causes the dump file to be erased prior to the new
4117     *    traces being written, if true; when false, the new traces will be
4118     *    appended to any existing file content.
4119     * @param firstPids of dalvik VM processes to dump stack traces for first
4120     * @param lastPids of dalvik VM processes to dump stack traces for last
4121     * @param nativeProcs optional list of native process names to dump stack crawls
4122     * @return file containing stack traces, or null if no dump file is configured
4123     */
4124    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4125            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4126        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4127        if (tracesPath == null || tracesPath.length() == 0) {
4128            return null;
4129        }
4130
4131        File tracesFile = new File(tracesPath);
4132        try {
4133            File tracesDir = tracesFile.getParentFile();
4134            if (!tracesDir.exists()) {
4135                tracesFile.mkdirs();
4136                if (!SELinux.restorecon(tracesDir)) {
4137                    return null;
4138                }
4139            }
4140            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4141
4142            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4143            tracesFile.createNewFile();
4144            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4145        } catch (IOException e) {
4146            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4147            return null;
4148        }
4149
4150        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4151        return tracesFile;
4152    }
4153
4154    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4155            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4156        // Use a FileObserver to detect when traces finish writing.
4157        // The order of traces is considered important to maintain for legibility.
4158        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4159            @Override
4160            public synchronized void onEvent(int event, String path) { notify(); }
4161        };
4162
4163        try {
4164            observer.startWatching();
4165
4166            // First collect all of the stacks of the most important pids.
4167            if (firstPids != null) {
4168                try {
4169                    int num = firstPids.size();
4170                    for (int i = 0; i < num; i++) {
4171                        synchronized (observer) {
4172                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4173                            observer.wait(200);  // Wait for write-close, give up after 200msec
4174                        }
4175                    }
4176                } catch (InterruptedException e) {
4177                    Log.wtf(TAG, e);
4178                }
4179            }
4180
4181            // Next collect the stacks of the native pids
4182            if (nativeProcs != null) {
4183                int[] pids = Process.getPidsForCommands(nativeProcs);
4184                if (pids != null) {
4185                    for (int pid : pids) {
4186                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4187                    }
4188                }
4189            }
4190
4191            // Lastly, measure CPU usage.
4192            if (processCpuTracker != null) {
4193                processCpuTracker.init();
4194                System.gc();
4195                processCpuTracker.update();
4196                try {
4197                    synchronized (processCpuTracker) {
4198                        processCpuTracker.wait(500); // measure over 1/2 second.
4199                    }
4200                } catch (InterruptedException e) {
4201                }
4202                processCpuTracker.update();
4203
4204                // We'll take the stack crawls of just the top apps using CPU.
4205                final int N = processCpuTracker.countWorkingStats();
4206                int numProcs = 0;
4207                for (int i=0; i<N && numProcs<5; i++) {
4208                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4209                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4210                        numProcs++;
4211                        try {
4212                            synchronized (observer) {
4213                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4214                                observer.wait(200);  // Wait for write-close, give up after 200msec
4215                            }
4216                        } catch (InterruptedException e) {
4217                            Log.wtf(TAG, e);
4218                        }
4219
4220                    }
4221                }
4222            }
4223        } finally {
4224            observer.stopWatching();
4225        }
4226    }
4227
4228    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4229        if (true || IS_USER_BUILD) {
4230            return;
4231        }
4232        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4233        if (tracesPath == null || tracesPath.length() == 0) {
4234            return;
4235        }
4236
4237        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4238        StrictMode.allowThreadDiskWrites();
4239        try {
4240            final File tracesFile = new File(tracesPath);
4241            final File tracesDir = tracesFile.getParentFile();
4242            final File tracesTmp = new File(tracesDir, "__tmp__");
4243            try {
4244                if (!tracesDir.exists()) {
4245                    tracesFile.mkdirs();
4246                    if (!SELinux.restorecon(tracesDir.getPath())) {
4247                        return;
4248                    }
4249                }
4250                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4251
4252                if (tracesFile.exists()) {
4253                    tracesTmp.delete();
4254                    tracesFile.renameTo(tracesTmp);
4255                }
4256                StringBuilder sb = new StringBuilder();
4257                Time tobj = new Time();
4258                tobj.set(System.currentTimeMillis());
4259                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4260                sb.append(": ");
4261                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4262                sb.append(" since ");
4263                sb.append(msg);
4264                FileOutputStream fos = new FileOutputStream(tracesFile);
4265                fos.write(sb.toString().getBytes());
4266                if (app == null) {
4267                    fos.write("\n*** No application process!".getBytes());
4268                }
4269                fos.close();
4270                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4271            } catch (IOException e) {
4272                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4273                return;
4274            }
4275
4276            if (app != null) {
4277                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4278                firstPids.add(app.pid);
4279                dumpStackTraces(tracesPath, firstPids, null, null, null);
4280            }
4281
4282            File lastTracesFile = null;
4283            File curTracesFile = null;
4284            for (int i=9; i>=0; i--) {
4285                String name = String.format(Locale.US, "slow%02d.txt", i);
4286                curTracesFile = new File(tracesDir, name);
4287                if (curTracesFile.exists()) {
4288                    if (lastTracesFile != null) {
4289                        curTracesFile.renameTo(lastTracesFile);
4290                    } else {
4291                        curTracesFile.delete();
4292                    }
4293                }
4294                lastTracesFile = curTracesFile;
4295            }
4296            tracesFile.renameTo(curTracesFile);
4297            if (tracesTmp.exists()) {
4298                tracesTmp.renameTo(tracesFile);
4299            }
4300        } finally {
4301            StrictMode.setThreadPolicy(oldPolicy);
4302        }
4303    }
4304
4305    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4306            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4307        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4308        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4309
4310        if (mController != null) {
4311            try {
4312                // 0 == continue, -1 = kill process immediately
4313                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4314                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4315            } catch (RemoteException e) {
4316                mController = null;
4317                Watchdog.getInstance().setActivityController(null);
4318            }
4319        }
4320
4321        long anrTime = SystemClock.uptimeMillis();
4322        if (MONITOR_CPU_USAGE) {
4323            updateCpuStatsNow();
4324        }
4325
4326        synchronized (this) {
4327            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4328            if (mShuttingDown) {
4329                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4330                return;
4331            } else if (app.notResponding) {
4332                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4333                return;
4334            } else if (app.crashing) {
4335                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4336                return;
4337            }
4338
4339            // In case we come through here for the same app before completing
4340            // this one, mark as anring now so we will bail out.
4341            app.notResponding = true;
4342
4343            // Log the ANR to the event log.
4344            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4345                    app.processName, app.info.flags, annotation);
4346
4347            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4348            firstPids.add(app.pid);
4349
4350            int parentPid = app.pid;
4351            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4352            if (parentPid != app.pid) firstPids.add(parentPid);
4353
4354            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4355
4356            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4357                ProcessRecord r = mLruProcesses.get(i);
4358                if (r != null && r.thread != null) {
4359                    int pid = r.pid;
4360                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4361                        if (r.persistent) {
4362                            firstPids.add(pid);
4363                        } else {
4364                            lastPids.put(pid, Boolean.TRUE);
4365                        }
4366                    }
4367                }
4368            }
4369        }
4370
4371        // Log the ANR to the main log.
4372        StringBuilder info = new StringBuilder();
4373        info.setLength(0);
4374        info.append("ANR in ").append(app.processName);
4375        if (activity != null && activity.shortComponentName != null) {
4376            info.append(" (").append(activity.shortComponentName).append(")");
4377        }
4378        info.append("\n");
4379        info.append("PID: ").append(app.pid).append("\n");
4380        if (annotation != null) {
4381            info.append("Reason: ").append(annotation).append("\n");
4382        }
4383        if (parent != null && parent != activity) {
4384            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4385        }
4386
4387        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4388
4389        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4390                NATIVE_STACKS_OF_INTEREST);
4391
4392        String cpuInfo = null;
4393        if (MONITOR_CPU_USAGE) {
4394            updateCpuStatsNow();
4395            synchronized (mProcessCpuThread) {
4396                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4397            }
4398            info.append(processCpuTracker.printCurrentLoad());
4399            info.append(cpuInfo);
4400        }
4401
4402        info.append(processCpuTracker.printCurrentState(anrTime));
4403
4404        Slog.e(TAG, info.toString());
4405        if (tracesFile == null) {
4406            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4407            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4408        }
4409
4410        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4411                cpuInfo, tracesFile, null);
4412
4413        if (mController != null) {
4414            try {
4415                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4416                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4417                if (res != 0) {
4418                    if (res < 0 && app.pid != MY_PID) {
4419                        Process.killProcess(app.pid);
4420                    } else {
4421                        synchronized (this) {
4422                            mServices.scheduleServiceTimeoutLocked(app);
4423                        }
4424                    }
4425                    return;
4426                }
4427            } catch (RemoteException e) {
4428                mController = null;
4429                Watchdog.getInstance().setActivityController(null);
4430            }
4431        }
4432
4433        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4434        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4435                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4436
4437        synchronized (this) {
4438            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4439                killUnneededProcessLocked(app, "background ANR");
4440                return;
4441            }
4442
4443            // Set the app's notResponding state, and look up the errorReportReceiver
4444            makeAppNotRespondingLocked(app,
4445                    activity != null ? activity.shortComponentName : null,
4446                    annotation != null ? "ANR " + annotation : "ANR",
4447                    info.toString());
4448
4449            // Bring up the infamous App Not Responding dialog
4450            Message msg = Message.obtain();
4451            HashMap<String, Object> map = new HashMap<String, Object>();
4452            msg.what = SHOW_NOT_RESPONDING_MSG;
4453            msg.obj = map;
4454            msg.arg1 = aboveSystem ? 1 : 0;
4455            map.put("app", app);
4456            if (activity != null) {
4457                map.put("activity", activity);
4458            }
4459
4460            mHandler.sendMessage(msg);
4461        }
4462    }
4463
4464    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4465        if (!mLaunchWarningShown) {
4466            mLaunchWarningShown = true;
4467            mHandler.post(new Runnable() {
4468                @Override
4469                public void run() {
4470                    synchronized (ActivityManagerService.this) {
4471                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4472                        d.show();
4473                        mHandler.postDelayed(new Runnable() {
4474                            @Override
4475                            public void run() {
4476                                synchronized (ActivityManagerService.this) {
4477                                    d.dismiss();
4478                                    mLaunchWarningShown = false;
4479                                }
4480                            }
4481                        }, 4000);
4482                    }
4483                }
4484            });
4485        }
4486    }
4487
4488    @Override
4489    public boolean clearApplicationUserData(final String packageName,
4490            final IPackageDataObserver observer, int userId) {
4491        enforceNotIsolatedCaller("clearApplicationUserData");
4492        int uid = Binder.getCallingUid();
4493        int pid = Binder.getCallingPid();
4494        userId = handleIncomingUser(pid, uid,
4495                userId, false, true, "clearApplicationUserData", null);
4496        long callingId = Binder.clearCallingIdentity();
4497        try {
4498            IPackageManager pm = AppGlobals.getPackageManager();
4499            int pkgUid = -1;
4500            synchronized(this) {
4501                try {
4502                    pkgUid = pm.getPackageUid(packageName, userId);
4503                } catch (RemoteException e) {
4504                }
4505                if (pkgUid == -1) {
4506                    Slog.w(TAG, "Invalid packageName: " + packageName);
4507                    if (observer != null) {
4508                        try {
4509                            observer.onRemoveCompleted(packageName, false);
4510                        } catch (RemoteException e) {
4511                            Slog.i(TAG, "Observer no longer exists.");
4512                        }
4513                    }
4514                    return false;
4515                }
4516                if (uid == pkgUid || checkComponentPermission(
4517                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4518                        pid, uid, -1, true)
4519                        == PackageManager.PERMISSION_GRANTED) {
4520                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4521                } else {
4522                    throw new SecurityException("PID " + pid + " does not have permission "
4523                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4524                                    + " of package " + packageName);
4525                }
4526            }
4527
4528            try {
4529                // Clear application user data
4530                pm.clearApplicationUserData(packageName, observer, userId);
4531
4532                // Remove all permissions granted from/to this package
4533                removeUriPermissionsForPackageLocked(packageName, userId, true);
4534
4535                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4536                        Uri.fromParts("package", packageName, null));
4537                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4538                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4539                        null, null, 0, null, null, null, false, false, userId);
4540            } catch (RemoteException e) {
4541            }
4542        } finally {
4543            Binder.restoreCallingIdentity(callingId);
4544        }
4545        return true;
4546    }
4547
4548    @Override
4549    public void killBackgroundProcesses(final String packageName, int userId) {
4550        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4551                != PackageManager.PERMISSION_GRANTED &&
4552                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4553                        != PackageManager.PERMISSION_GRANTED) {
4554            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4555                    + Binder.getCallingPid()
4556                    + ", uid=" + Binder.getCallingUid()
4557                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4558            Slog.w(TAG, msg);
4559            throw new SecurityException(msg);
4560        }
4561
4562        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4563                userId, true, true, "killBackgroundProcesses", null);
4564        long callingId = Binder.clearCallingIdentity();
4565        try {
4566            IPackageManager pm = AppGlobals.getPackageManager();
4567            synchronized(this) {
4568                int appId = -1;
4569                try {
4570                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4571                } catch (RemoteException e) {
4572                }
4573                if (appId == -1) {
4574                    Slog.w(TAG, "Invalid packageName: " + packageName);
4575                    return;
4576                }
4577                killPackageProcessesLocked(packageName, appId, userId,
4578                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4579            }
4580        } finally {
4581            Binder.restoreCallingIdentity(callingId);
4582        }
4583    }
4584
4585    @Override
4586    public void killAllBackgroundProcesses() {
4587        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4588                != PackageManager.PERMISSION_GRANTED) {
4589            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4590                    + Binder.getCallingPid()
4591                    + ", uid=" + Binder.getCallingUid()
4592                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4593            Slog.w(TAG, msg);
4594            throw new SecurityException(msg);
4595        }
4596
4597        long callingId = Binder.clearCallingIdentity();
4598        try {
4599            synchronized(this) {
4600                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4601                final int NP = mProcessNames.getMap().size();
4602                for (int ip=0; ip<NP; ip++) {
4603                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4604                    final int NA = apps.size();
4605                    for (int ia=0; ia<NA; ia++) {
4606                        ProcessRecord app = apps.valueAt(ia);
4607                        if (app.persistent) {
4608                            // we don't kill persistent processes
4609                            continue;
4610                        }
4611                        if (app.removed) {
4612                            procs.add(app);
4613                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4614                            app.removed = true;
4615                            procs.add(app);
4616                        }
4617                    }
4618                }
4619
4620                int N = procs.size();
4621                for (int i=0; i<N; i++) {
4622                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4623                }
4624                mAllowLowerMemLevel = true;
4625                updateOomAdjLocked();
4626                doLowMemReportIfNeededLocked(null);
4627            }
4628        } finally {
4629            Binder.restoreCallingIdentity(callingId);
4630        }
4631    }
4632
4633    @Override
4634    public void forceStopPackage(final String packageName, int userId) {
4635        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4636                != PackageManager.PERMISSION_GRANTED) {
4637            String msg = "Permission Denial: forceStopPackage() from pid="
4638                    + Binder.getCallingPid()
4639                    + ", uid=" + Binder.getCallingUid()
4640                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4641            Slog.w(TAG, msg);
4642            throw new SecurityException(msg);
4643        }
4644        final int callingPid = Binder.getCallingPid();
4645        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4646                userId, true, true, "forceStopPackage", null);
4647        long callingId = Binder.clearCallingIdentity();
4648        try {
4649            IPackageManager pm = AppGlobals.getPackageManager();
4650            synchronized(this) {
4651                int[] users = userId == UserHandle.USER_ALL
4652                        ? getUsersLocked() : new int[] { userId };
4653                for (int user : users) {
4654                    int pkgUid = -1;
4655                    try {
4656                        pkgUid = pm.getPackageUid(packageName, user);
4657                    } catch (RemoteException e) {
4658                    }
4659                    if (pkgUid == -1) {
4660                        Slog.w(TAG, "Invalid packageName: " + packageName);
4661                        continue;
4662                    }
4663                    try {
4664                        pm.setPackageStoppedState(packageName, true, user);
4665                    } catch (RemoteException e) {
4666                    } catch (IllegalArgumentException e) {
4667                        Slog.w(TAG, "Failed trying to unstop package "
4668                                + packageName + ": " + e);
4669                    }
4670                    if (isUserRunningLocked(user, false)) {
4671                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4672                    }
4673                }
4674            }
4675        } finally {
4676            Binder.restoreCallingIdentity(callingId);
4677        }
4678    }
4679
4680    /*
4681     * The pkg name and app id have to be specified.
4682     */
4683    @Override
4684    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4685        if (pkg == null) {
4686            return;
4687        }
4688        // Make sure the uid is valid.
4689        if (appid < 0) {
4690            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4691            return;
4692        }
4693        int callerUid = Binder.getCallingUid();
4694        // Only the system server can kill an application
4695        if (callerUid == Process.SYSTEM_UID) {
4696            // Post an aysnc message to kill the application
4697            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4698            msg.arg1 = appid;
4699            msg.arg2 = 0;
4700            Bundle bundle = new Bundle();
4701            bundle.putString("pkg", pkg);
4702            bundle.putString("reason", reason);
4703            msg.obj = bundle;
4704            mHandler.sendMessage(msg);
4705        } else {
4706            throw new SecurityException(callerUid + " cannot kill pkg: " +
4707                    pkg);
4708        }
4709    }
4710
4711    @Override
4712    public void closeSystemDialogs(String reason) {
4713        enforceNotIsolatedCaller("closeSystemDialogs");
4714
4715        final int pid = Binder.getCallingPid();
4716        final int uid = Binder.getCallingUid();
4717        final long origId = Binder.clearCallingIdentity();
4718        try {
4719            synchronized (this) {
4720                // Only allow this from foreground processes, so that background
4721                // applications can't abuse it to prevent system UI from being shown.
4722                if (uid >= Process.FIRST_APPLICATION_UID) {
4723                    ProcessRecord proc;
4724                    synchronized (mPidsSelfLocked) {
4725                        proc = mPidsSelfLocked.get(pid);
4726                    }
4727                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4728                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4729                                + " from background process " + proc);
4730                        return;
4731                    }
4732                }
4733                closeSystemDialogsLocked(reason);
4734            }
4735        } finally {
4736            Binder.restoreCallingIdentity(origId);
4737        }
4738    }
4739
4740    void closeSystemDialogsLocked(String reason) {
4741        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4742        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4743                | Intent.FLAG_RECEIVER_FOREGROUND);
4744        if (reason != null) {
4745            intent.putExtra("reason", reason);
4746        }
4747        mWindowManager.closeSystemDialogs(reason);
4748
4749        mStackSupervisor.closeSystemDialogsLocked();
4750
4751        broadcastIntentLocked(null, null, intent, null,
4752                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4753                Process.SYSTEM_UID, UserHandle.USER_ALL);
4754    }
4755
4756    @Override
4757    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4758        enforceNotIsolatedCaller("getProcessMemoryInfo");
4759        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4760        for (int i=pids.length-1; i>=0; i--) {
4761            ProcessRecord proc;
4762            int oomAdj;
4763            synchronized (this) {
4764                synchronized (mPidsSelfLocked) {
4765                    proc = mPidsSelfLocked.get(pids[i]);
4766                    oomAdj = proc != null ? proc.setAdj : 0;
4767                }
4768            }
4769            infos[i] = new Debug.MemoryInfo();
4770            Debug.getMemoryInfo(pids[i], infos[i]);
4771            if (proc != null) {
4772                synchronized (this) {
4773                    if (proc.thread != null && proc.setAdj == oomAdj) {
4774                        // Record this for posterity if the process has been stable.
4775                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4776                                infos[i].getTotalUss(), false, proc.pkgList);
4777                    }
4778                }
4779            }
4780        }
4781        return infos;
4782    }
4783
4784    @Override
4785    public long[] getProcessPss(int[] pids) {
4786        enforceNotIsolatedCaller("getProcessPss");
4787        long[] pss = new long[pids.length];
4788        for (int i=pids.length-1; i>=0; i--) {
4789            ProcessRecord proc;
4790            int oomAdj;
4791            synchronized (this) {
4792                synchronized (mPidsSelfLocked) {
4793                    proc = mPidsSelfLocked.get(pids[i]);
4794                    oomAdj = proc != null ? proc.setAdj : 0;
4795                }
4796            }
4797            long[] tmpUss = new long[1];
4798            pss[i] = Debug.getPss(pids[i], tmpUss);
4799            if (proc != null) {
4800                synchronized (this) {
4801                    if (proc.thread != null && proc.setAdj == oomAdj) {
4802                        // Record this for posterity if the process has been stable.
4803                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4804                    }
4805                }
4806            }
4807        }
4808        return pss;
4809    }
4810
4811    @Override
4812    public void killApplicationProcess(String processName, int uid) {
4813        if (processName == null) {
4814            return;
4815        }
4816
4817        int callerUid = Binder.getCallingUid();
4818        // Only the system server can kill an application
4819        if (callerUid == Process.SYSTEM_UID) {
4820            synchronized (this) {
4821                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4822                if (app != null && app.thread != null) {
4823                    try {
4824                        app.thread.scheduleSuicide();
4825                    } catch (RemoteException e) {
4826                        // If the other end already died, then our work here is done.
4827                    }
4828                } else {
4829                    Slog.w(TAG, "Process/uid not found attempting kill of "
4830                            + processName + " / " + uid);
4831                }
4832            }
4833        } else {
4834            throw new SecurityException(callerUid + " cannot kill app process: " +
4835                    processName);
4836        }
4837    }
4838
4839    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4840        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4841                false, true, false, false, UserHandle.getUserId(uid), reason);
4842        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4843                Uri.fromParts("package", packageName, null));
4844        if (!mProcessesReady) {
4845            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4846                    | Intent.FLAG_RECEIVER_FOREGROUND);
4847        }
4848        intent.putExtra(Intent.EXTRA_UID, uid);
4849        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4850        broadcastIntentLocked(null, null, intent,
4851                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4852                false, false,
4853                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4854    }
4855
4856    private void forceStopUserLocked(int userId, String reason) {
4857        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4858        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4859        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4860                | Intent.FLAG_RECEIVER_FOREGROUND);
4861        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4862        broadcastIntentLocked(null, null, intent,
4863                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4864                false, false,
4865                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4866    }
4867
4868    private final boolean killPackageProcessesLocked(String packageName, int appId,
4869            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4870            boolean doit, boolean evenPersistent, String reason) {
4871        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4872
4873        // Remove all processes this package may have touched: all with the
4874        // same UID (except for the system or root user), and all whose name
4875        // matches the package name.
4876        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4877        final int NP = mProcessNames.getMap().size();
4878        for (int ip=0; ip<NP; ip++) {
4879            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4880            final int NA = apps.size();
4881            for (int ia=0; ia<NA; ia++) {
4882                ProcessRecord app = apps.valueAt(ia);
4883                if (app.persistent && !evenPersistent) {
4884                    // we don't kill persistent processes
4885                    continue;
4886                }
4887                if (app.removed) {
4888                    if (doit) {
4889                        procs.add(app);
4890                    }
4891                    continue;
4892                }
4893
4894                // Skip process if it doesn't meet our oom adj requirement.
4895                if (app.setAdj < minOomAdj) {
4896                    continue;
4897                }
4898
4899                // If no package is specified, we call all processes under the
4900                // give user id.
4901                if (packageName == null) {
4902                    if (app.userId != userId) {
4903                        continue;
4904                    }
4905                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4906                        continue;
4907                    }
4908                // Package has been specified, we want to hit all processes
4909                // that match it.  We need to qualify this by the processes
4910                // that are running under the specified app and user ID.
4911                } else {
4912                    if (UserHandle.getAppId(app.uid) != appId) {
4913                        continue;
4914                    }
4915                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4916                        continue;
4917                    }
4918                    if (!app.pkgList.containsKey(packageName)) {
4919                        continue;
4920                    }
4921                }
4922
4923                // Process has passed all conditions, kill it!
4924                if (!doit) {
4925                    return true;
4926                }
4927                app.removed = true;
4928                procs.add(app);
4929            }
4930        }
4931
4932        int N = procs.size();
4933        for (int i=0; i<N; i++) {
4934            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4935        }
4936        updateOomAdjLocked();
4937        return N > 0;
4938    }
4939
4940    private final boolean forceStopPackageLocked(String name, int appId,
4941            boolean callerWillRestart, boolean purgeCache, boolean doit,
4942            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4943        int i;
4944        int N;
4945
4946        if (userId == UserHandle.USER_ALL && name == null) {
4947            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4948        }
4949
4950        if (appId < 0 && name != null) {
4951            try {
4952                appId = UserHandle.getAppId(
4953                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4954            } catch (RemoteException e) {
4955            }
4956        }
4957
4958        if (doit) {
4959            if (name != null) {
4960                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4961                        + " user=" + userId + ": " + reason);
4962            } else {
4963                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4964            }
4965
4966            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4967            for (int ip=pmap.size()-1; ip>=0; ip--) {
4968                SparseArray<Long> ba = pmap.valueAt(ip);
4969                for (i=ba.size()-1; i>=0; i--) {
4970                    boolean remove = false;
4971                    final int entUid = ba.keyAt(i);
4972                    if (name != null) {
4973                        if (userId == UserHandle.USER_ALL) {
4974                            if (UserHandle.getAppId(entUid) == appId) {
4975                                remove = true;
4976                            }
4977                        } else {
4978                            if (entUid == UserHandle.getUid(userId, appId)) {
4979                                remove = true;
4980                            }
4981                        }
4982                    } else if (UserHandle.getUserId(entUid) == userId) {
4983                        remove = true;
4984                    }
4985                    if (remove) {
4986                        ba.removeAt(i);
4987                    }
4988                }
4989                if (ba.size() == 0) {
4990                    pmap.removeAt(ip);
4991                }
4992            }
4993        }
4994
4995        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4996                -100, callerWillRestart, true, doit, evenPersistent,
4997                name == null ? ("stop user " + userId) : ("stop " + name));
4998
4999        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5000            if (!doit) {
5001                return true;
5002            }
5003            didSomething = true;
5004        }
5005
5006        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5007            if (!doit) {
5008                return true;
5009            }
5010            didSomething = true;
5011        }
5012
5013        if (name == null) {
5014            // Remove all sticky broadcasts from this user.
5015            mStickyBroadcasts.remove(userId);
5016        }
5017
5018        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5019        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5020                userId, providers)) {
5021            if (!doit) {
5022                return true;
5023            }
5024            didSomething = true;
5025        }
5026        N = providers.size();
5027        for (i=0; i<N; i++) {
5028            removeDyingProviderLocked(null, providers.get(i), true);
5029        }
5030
5031        // Remove transient permissions granted from/to this package/user
5032        removeUriPermissionsForPackageLocked(name, userId, false);
5033
5034        if (name == null || uninstalling) {
5035            // Remove pending intents.  For now we only do this when force
5036            // stopping users, because we have some problems when doing this
5037            // for packages -- app widgets are not currently cleaned up for
5038            // such packages, so they can be left with bad pending intents.
5039            if (mIntentSenderRecords.size() > 0) {
5040                Iterator<WeakReference<PendingIntentRecord>> it
5041                        = mIntentSenderRecords.values().iterator();
5042                while (it.hasNext()) {
5043                    WeakReference<PendingIntentRecord> wpir = it.next();
5044                    if (wpir == null) {
5045                        it.remove();
5046                        continue;
5047                    }
5048                    PendingIntentRecord pir = wpir.get();
5049                    if (pir == null) {
5050                        it.remove();
5051                        continue;
5052                    }
5053                    if (name == null) {
5054                        // Stopping user, remove all objects for the user.
5055                        if (pir.key.userId != userId) {
5056                            // Not the same user, skip it.
5057                            continue;
5058                        }
5059                    } else {
5060                        if (UserHandle.getAppId(pir.uid) != appId) {
5061                            // Different app id, skip it.
5062                            continue;
5063                        }
5064                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5065                            // Different user, skip it.
5066                            continue;
5067                        }
5068                        if (!pir.key.packageName.equals(name)) {
5069                            // Different package, skip it.
5070                            continue;
5071                        }
5072                    }
5073                    if (!doit) {
5074                        return true;
5075                    }
5076                    didSomething = true;
5077                    it.remove();
5078                    pir.canceled = true;
5079                    if (pir.key.activity != null) {
5080                        pir.key.activity.pendingResults.remove(pir.ref);
5081                    }
5082                }
5083            }
5084        }
5085
5086        if (doit) {
5087            if (purgeCache && name != null) {
5088                AttributeCache ac = AttributeCache.instance();
5089                if (ac != null) {
5090                    ac.removePackage(name);
5091                }
5092            }
5093            if (mBooted) {
5094                mStackSupervisor.resumeTopActivitiesLocked();
5095                mStackSupervisor.scheduleIdleLocked();
5096            }
5097        }
5098
5099        return didSomething;
5100    }
5101
5102    private final boolean removeProcessLocked(ProcessRecord app,
5103            boolean callerWillRestart, boolean allowRestart, String reason) {
5104        final String name = app.processName;
5105        final int uid = app.uid;
5106        if (DEBUG_PROCESSES) Slog.d(
5107            TAG, "Force removing proc " + app.toShortString() + " (" + name
5108            + "/" + uid + ")");
5109
5110        mProcessNames.remove(name, uid);
5111        mIsolatedProcesses.remove(app.uid);
5112        if (mHeavyWeightProcess == app) {
5113            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5114                    mHeavyWeightProcess.userId, 0));
5115            mHeavyWeightProcess = null;
5116        }
5117        boolean needRestart = false;
5118        if (app.pid > 0 && app.pid != MY_PID) {
5119            int pid = app.pid;
5120            synchronized (mPidsSelfLocked) {
5121                mPidsSelfLocked.remove(pid);
5122                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5123            }
5124            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5125                    app.processName, app.info.uid);
5126            if (app.isolated) {
5127                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5128            }
5129            killUnneededProcessLocked(app, reason);
5130            handleAppDiedLocked(app, true, allowRestart);
5131            removeLruProcessLocked(app);
5132
5133            if (app.persistent && !app.isolated) {
5134                if (!callerWillRestart) {
5135                    addAppLocked(app.info, false, null /* ABI override */);
5136                } else {
5137                    needRestart = true;
5138                }
5139            }
5140        } else {
5141            mRemovedProcesses.add(app);
5142        }
5143
5144        return needRestart;
5145    }
5146
5147    private final void processStartTimedOutLocked(ProcessRecord app) {
5148        final int pid = app.pid;
5149        boolean gone = false;
5150        synchronized (mPidsSelfLocked) {
5151            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5152            if (knownApp != null && knownApp.thread == null) {
5153                mPidsSelfLocked.remove(pid);
5154                gone = true;
5155            }
5156        }
5157
5158        if (gone) {
5159            Slog.w(TAG, "Process " + app + " failed to attach");
5160            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5161                    pid, app.uid, app.processName);
5162            mProcessNames.remove(app.processName, app.uid);
5163            mIsolatedProcesses.remove(app.uid);
5164            if (mHeavyWeightProcess == app) {
5165                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5166                        mHeavyWeightProcess.userId, 0));
5167                mHeavyWeightProcess = null;
5168            }
5169            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5170                    app.processName, app.info.uid);
5171            if (app.isolated) {
5172                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5173            }
5174            // Take care of any launching providers waiting for this process.
5175            checkAppInLaunchingProvidersLocked(app, true);
5176            // Take care of any services that are waiting for the process.
5177            mServices.processStartTimedOutLocked(app);
5178            killUnneededProcessLocked(app, "start timeout");
5179            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5180                Slog.w(TAG, "Unattached app died before backup, skipping");
5181                try {
5182                    IBackupManager bm = IBackupManager.Stub.asInterface(
5183                            ServiceManager.getService(Context.BACKUP_SERVICE));
5184                    bm.agentDisconnected(app.info.packageName);
5185                } catch (RemoteException e) {
5186                    // Can't happen; the backup manager is local
5187                }
5188            }
5189            if (isPendingBroadcastProcessLocked(pid)) {
5190                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5191                skipPendingBroadcastLocked(pid);
5192            }
5193        } else {
5194            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5195        }
5196    }
5197
5198    private final boolean attachApplicationLocked(IApplicationThread thread,
5199            int pid) {
5200
5201        // Find the application record that is being attached...  either via
5202        // the pid if we are running in multiple processes, or just pull the
5203        // next app record if we are emulating process with anonymous threads.
5204        ProcessRecord app;
5205        if (pid != MY_PID && pid >= 0) {
5206            synchronized (mPidsSelfLocked) {
5207                app = mPidsSelfLocked.get(pid);
5208            }
5209        } else {
5210            app = null;
5211        }
5212
5213        if (app == null) {
5214            Slog.w(TAG, "No pending application record for pid " + pid
5215                    + " (IApplicationThread " + thread + "); dropping process");
5216            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5217            if (pid > 0 && pid != MY_PID) {
5218                Process.killProcessQuiet(pid);
5219            } else {
5220                try {
5221                    thread.scheduleExit();
5222                } catch (Exception e) {
5223                    // Ignore exceptions.
5224                }
5225            }
5226            return false;
5227        }
5228
5229        // If this application record is still attached to a previous
5230        // process, clean it up now.
5231        if (app.thread != null) {
5232            handleAppDiedLocked(app, true, true);
5233        }
5234
5235        // Tell the process all about itself.
5236
5237        if (localLOGV) Slog.v(
5238                TAG, "Binding process pid " + pid + " to record " + app);
5239
5240        final String processName = app.processName;
5241        try {
5242            AppDeathRecipient adr = new AppDeathRecipient(
5243                    app, pid, thread);
5244            thread.asBinder().linkToDeath(adr, 0);
5245            app.deathRecipient = adr;
5246        } catch (RemoteException e) {
5247            app.resetPackageList(mProcessStats);
5248            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5249            return false;
5250        }
5251
5252        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5253
5254        app.makeActive(thread, mProcessStats);
5255        app.curAdj = app.setAdj = -100;
5256        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5257        app.forcingToForeground = null;
5258        updateProcessForegroundLocked(app, false, false);
5259        app.hasShownUi = false;
5260        app.debugging = false;
5261        app.cached = false;
5262
5263        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5264
5265        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5266        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5267
5268        if (!normalMode) {
5269            Slog.i(TAG, "Launching preboot mode app: " + app);
5270        }
5271
5272        if (localLOGV) Slog.v(
5273            TAG, "New app record " + app
5274            + " thread=" + thread.asBinder() + " pid=" + pid);
5275        try {
5276            int testMode = IApplicationThread.DEBUG_OFF;
5277            if (mDebugApp != null && mDebugApp.equals(processName)) {
5278                testMode = mWaitForDebugger
5279                    ? IApplicationThread.DEBUG_WAIT
5280                    : IApplicationThread.DEBUG_ON;
5281                app.debugging = true;
5282                if (mDebugTransient) {
5283                    mDebugApp = mOrigDebugApp;
5284                    mWaitForDebugger = mOrigWaitForDebugger;
5285                }
5286            }
5287            String profileFile = app.instrumentationProfileFile;
5288            ParcelFileDescriptor profileFd = null;
5289            boolean profileAutoStop = false;
5290            if (mProfileApp != null && mProfileApp.equals(processName)) {
5291                mProfileProc = app;
5292                profileFile = mProfileFile;
5293                profileFd = mProfileFd;
5294                profileAutoStop = mAutoStopProfiler;
5295            }
5296            boolean enableOpenGlTrace = false;
5297            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5298                enableOpenGlTrace = true;
5299                mOpenGlTraceApp = null;
5300            }
5301
5302            // If the app is being launched for restore or full backup, set it up specially
5303            boolean isRestrictedBackupMode = false;
5304            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5305                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5306                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5307                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5308            }
5309
5310            ensurePackageDexOpt(app.instrumentationInfo != null
5311                    ? app.instrumentationInfo.packageName
5312                    : app.info.packageName);
5313            if (app.instrumentationClass != null) {
5314                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5315            }
5316            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5317                    + processName + " with config " + mConfiguration);
5318            ApplicationInfo appInfo = app.instrumentationInfo != null
5319                    ? app.instrumentationInfo : app.info;
5320            app.compat = compatibilityInfoForPackageLocked(appInfo);
5321            if (profileFd != null) {
5322                profileFd = profileFd.dup();
5323            }
5324            thread.bindApplication(processName, appInfo, providers,
5325                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5326                    app.instrumentationArguments, app.instrumentationWatcher,
5327                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5328                    isRestrictedBackupMode || !normalMode, app.persistent,
5329                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5330                    mCoreSettingsObserver.getCoreSettingsLocked());
5331            updateLruProcessLocked(app, false, null);
5332            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5333        } catch (Exception e) {
5334            // todo: Yikes!  What should we do?  For now we will try to
5335            // start another process, but that could easily get us in
5336            // an infinite loop of restarting processes...
5337            Slog.w(TAG, "Exception thrown during bind!", e);
5338
5339            app.resetPackageList(mProcessStats);
5340            app.unlinkDeathRecipient();
5341            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5342            return false;
5343        }
5344
5345        // Remove this record from the list of starting applications.
5346        mPersistentStartingProcesses.remove(app);
5347        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5348                "Attach application locked removing on hold: " + app);
5349        mProcessesOnHold.remove(app);
5350
5351        boolean badApp = false;
5352        boolean didSomething = false;
5353
5354        // See if the top visible activity is waiting to run in this process...
5355        if (normalMode) {
5356            try {
5357                if (mStackSupervisor.attachApplicationLocked(app)) {
5358                    didSomething = true;
5359                }
5360            } catch (Exception e) {
5361                badApp = true;
5362            }
5363        }
5364
5365        // Find any services that should be running in this process...
5366        if (!badApp) {
5367            try {
5368                didSomething |= mServices.attachApplicationLocked(app, processName);
5369            } catch (Exception e) {
5370                badApp = true;
5371            }
5372        }
5373
5374        // Check if a next-broadcast receiver is in this process...
5375        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5376            try {
5377                didSomething |= sendPendingBroadcastsLocked(app);
5378            } catch (Exception e) {
5379                // If the app died trying to launch the receiver we declare it 'bad'
5380                badApp = true;
5381            }
5382        }
5383
5384        // Check whether the next backup agent is in this process...
5385        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5386            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5387            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5388            try {
5389                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5390                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5391                        mBackupTarget.backupMode);
5392            } catch (Exception e) {
5393                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5394                e.printStackTrace();
5395            }
5396        }
5397
5398        if (badApp) {
5399            // todo: Also need to kill application to deal with all
5400            // kinds of exceptions.
5401            handleAppDiedLocked(app, false, true);
5402            return false;
5403        }
5404
5405        if (!didSomething) {
5406            updateOomAdjLocked();
5407        }
5408
5409        return true;
5410    }
5411
5412    @Override
5413    public final void attachApplication(IApplicationThread thread) {
5414        synchronized (this) {
5415            int callingPid = Binder.getCallingPid();
5416            final long origId = Binder.clearCallingIdentity();
5417            attachApplicationLocked(thread, callingPid);
5418            Binder.restoreCallingIdentity(origId);
5419        }
5420    }
5421
5422    @Override
5423    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5424        final long origId = Binder.clearCallingIdentity();
5425        synchronized (this) {
5426            ActivityStack stack = ActivityRecord.getStackLocked(token);
5427            if (stack != null) {
5428                ActivityRecord r =
5429                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5430                if (stopProfiling) {
5431                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5432                        try {
5433                            mProfileFd.close();
5434                        } catch (IOException e) {
5435                        }
5436                        clearProfilerLocked();
5437                    }
5438                }
5439            }
5440        }
5441        Binder.restoreCallingIdentity(origId);
5442    }
5443
5444    void enableScreenAfterBoot() {
5445        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5446                SystemClock.uptimeMillis());
5447        mWindowManager.enableScreenAfterBoot();
5448
5449        synchronized (this) {
5450            updateEventDispatchingLocked();
5451        }
5452    }
5453
5454    @Override
5455    public void showBootMessage(final CharSequence msg, final boolean always) {
5456        enforceNotIsolatedCaller("showBootMessage");
5457        mWindowManager.showBootMessage(msg, always);
5458    }
5459
5460    @Override
5461    public void dismissKeyguardOnNextActivity() {
5462        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5463        final long token = Binder.clearCallingIdentity();
5464        try {
5465            synchronized (this) {
5466                if (DEBUG_LOCKSCREEN) logLockScreen("");
5467                if (mLockScreenShown) {
5468                    mLockScreenShown = false;
5469                    comeOutOfSleepIfNeededLocked();
5470                }
5471                mStackSupervisor.setDismissKeyguard(true);
5472            }
5473        } finally {
5474            Binder.restoreCallingIdentity(token);
5475        }
5476    }
5477
5478    final void finishBooting() {
5479        // Register receivers to handle package update events
5480        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5481
5482        synchronized (this) {
5483            // Ensure that any processes we had put on hold are now started
5484            // up.
5485            final int NP = mProcessesOnHold.size();
5486            if (NP > 0) {
5487                ArrayList<ProcessRecord> procs =
5488                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5489                for (int ip=0; ip<NP; ip++) {
5490                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5491                            + procs.get(ip));
5492                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5493                }
5494            }
5495
5496            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5497                // Start looking for apps that are abusing wake locks.
5498                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5499                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5500                // Tell anyone interested that we are done booting!
5501                SystemProperties.set("sys.boot_completed", "1");
5502                SystemProperties.set("dev.bootcomplete", "1");
5503                for (int i=0; i<mStartedUsers.size(); i++) {
5504                    UserStartedState uss = mStartedUsers.valueAt(i);
5505                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5506                        uss.mState = UserStartedState.STATE_RUNNING;
5507                        final int userId = mStartedUsers.keyAt(i);
5508                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5509                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5510                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5511                        broadcastIntentLocked(null, null, intent, null,
5512                                new IIntentReceiver.Stub() {
5513                                    @Override
5514                                    public void performReceive(Intent intent, int resultCode,
5515                                            String data, Bundle extras, boolean ordered,
5516                                            boolean sticky, int sendingUser) {
5517                                        synchronized (ActivityManagerService.this) {
5518                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5519                                                    true, false);
5520                                        }
5521                                    }
5522                                },
5523                                0, null, null,
5524                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5525                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5526                                userId);
5527                    }
5528                }
5529                scheduleStartProfilesLocked();
5530            }
5531        }
5532    }
5533
5534    final void ensureBootCompleted() {
5535        boolean booting;
5536        boolean enableScreen;
5537        synchronized (this) {
5538            booting = mBooting;
5539            mBooting = false;
5540            enableScreen = !mBooted;
5541            mBooted = true;
5542        }
5543
5544        if (booting) {
5545            finishBooting();
5546        }
5547
5548        if (enableScreen) {
5549            enableScreenAfterBoot();
5550        }
5551    }
5552
5553    @Override
5554    public final void activityResumed(IBinder token) {
5555        final long origId = Binder.clearCallingIdentity();
5556        synchronized(this) {
5557            ActivityStack stack = ActivityRecord.getStackLocked(token);
5558            if (stack != null) {
5559                ActivityRecord.activityResumedLocked(token);
5560            }
5561        }
5562        Binder.restoreCallingIdentity(origId);
5563    }
5564
5565    @Override
5566    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5567        final long origId = Binder.clearCallingIdentity();
5568        synchronized(this) {
5569            ActivityStack stack = ActivityRecord.getStackLocked(token);
5570            if (stack != null) {
5571                stack.activityPausedLocked(token, false, persistentState);
5572            }
5573        }
5574        Binder.restoreCallingIdentity(origId);
5575    }
5576
5577    @Override
5578    public final void activityStopped(IBinder token, Bundle icicle,
5579            PersistableBundle persistentState, CharSequence description) {
5580        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5581
5582        // Refuse possible leaked file descriptors
5583        if (icicle != null && icicle.hasFileDescriptors()) {
5584            throw new IllegalArgumentException("File descriptors passed in Bundle");
5585        }
5586
5587        final long origId = Binder.clearCallingIdentity();
5588
5589        synchronized (this) {
5590            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5591            if (r != null) {
5592                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5593            }
5594        }
5595
5596        trimApplications();
5597
5598        Binder.restoreCallingIdentity(origId);
5599    }
5600
5601    @Override
5602    public final void activityDestroyed(IBinder token) {
5603        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5604        synchronized (this) {
5605            ActivityStack stack = ActivityRecord.getStackLocked(token);
5606            if (stack != null) {
5607                stack.activityDestroyedLocked(token);
5608            }
5609        }
5610    }
5611
5612    @Override
5613    public String getCallingPackage(IBinder token) {
5614        synchronized (this) {
5615            ActivityRecord r = getCallingRecordLocked(token);
5616            return r != null ? r.info.packageName : null;
5617        }
5618    }
5619
5620    @Override
5621    public ComponentName getCallingActivity(IBinder token) {
5622        synchronized (this) {
5623            ActivityRecord r = getCallingRecordLocked(token);
5624            return r != null ? r.intent.getComponent() : null;
5625        }
5626    }
5627
5628    private ActivityRecord getCallingRecordLocked(IBinder token) {
5629        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5630        if (r == null) {
5631            return null;
5632        }
5633        return r.resultTo;
5634    }
5635
5636    @Override
5637    public ComponentName getActivityClassForToken(IBinder token) {
5638        synchronized(this) {
5639            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5640            if (r == null) {
5641                return null;
5642            }
5643            return r.intent.getComponent();
5644        }
5645    }
5646
5647    @Override
5648    public String getPackageForToken(IBinder token) {
5649        synchronized(this) {
5650            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5651            if (r == null) {
5652                return null;
5653            }
5654            return r.packageName;
5655        }
5656    }
5657
5658    @Override
5659    public IIntentSender getIntentSender(int type,
5660            String packageName, IBinder token, String resultWho,
5661            int requestCode, Intent[] intents, String[] resolvedTypes,
5662            int flags, Bundle options, int userId) {
5663        enforceNotIsolatedCaller("getIntentSender");
5664        // Refuse possible leaked file descriptors
5665        if (intents != null) {
5666            if (intents.length < 1) {
5667                throw new IllegalArgumentException("Intents array length must be >= 1");
5668            }
5669            for (int i=0; i<intents.length; i++) {
5670                Intent intent = intents[i];
5671                if (intent != null) {
5672                    if (intent.hasFileDescriptors()) {
5673                        throw new IllegalArgumentException("File descriptors passed in Intent");
5674                    }
5675                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5676                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5677                        throw new IllegalArgumentException(
5678                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5679                    }
5680                    intents[i] = new Intent(intent);
5681                }
5682            }
5683            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5684                throw new IllegalArgumentException(
5685                        "Intent array length does not match resolvedTypes length");
5686            }
5687        }
5688        if (options != null) {
5689            if (options.hasFileDescriptors()) {
5690                throw new IllegalArgumentException("File descriptors passed in options");
5691            }
5692        }
5693
5694        synchronized(this) {
5695            int callingUid = Binder.getCallingUid();
5696            int origUserId = userId;
5697            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5698                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5699                    "getIntentSender", null);
5700            if (origUserId == UserHandle.USER_CURRENT) {
5701                // We don't want to evaluate this until the pending intent is
5702                // actually executed.  However, we do want to always do the
5703                // security checking for it above.
5704                userId = UserHandle.USER_CURRENT;
5705            }
5706            try {
5707                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5708                    int uid = AppGlobals.getPackageManager()
5709                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5710                    if (!UserHandle.isSameApp(callingUid, uid)) {
5711                        String msg = "Permission Denial: getIntentSender() from pid="
5712                            + Binder.getCallingPid()
5713                            + ", uid=" + Binder.getCallingUid()
5714                            + ", (need uid=" + uid + ")"
5715                            + " is not allowed to send as package " + packageName;
5716                        Slog.w(TAG, msg);
5717                        throw new SecurityException(msg);
5718                    }
5719                }
5720
5721                return getIntentSenderLocked(type, packageName, callingUid, userId,
5722                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5723
5724            } catch (RemoteException e) {
5725                throw new SecurityException(e);
5726            }
5727        }
5728    }
5729
5730    IIntentSender getIntentSenderLocked(int type, String packageName,
5731            int callingUid, int userId, IBinder token, String resultWho,
5732            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5733            Bundle options) {
5734        if (DEBUG_MU)
5735            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5736        ActivityRecord activity = null;
5737        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5738            activity = ActivityRecord.isInStackLocked(token);
5739            if (activity == null) {
5740                return null;
5741            }
5742            if (activity.finishing) {
5743                return null;
5744            }
5745        }
5746
5747        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5748        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5749        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5750        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5751                |PendingIntent.FLAG_UPDATE_CURRENT);
5752
5753        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5754                type, packageName, activity, resultWho,
5755                requestCode, intents, resolvedTypes, flags, options, userId);
5756        WeakReference<PendingIntentRecord> ref;
5757        ref = mIntentSenderRecords.get(key);
5758        PendingIntentRecord rec = ref != null ? ref.get() : null;
5759        if (rec != null) {
5760            if (!cancelCurrent) {
5761                if (updateCurrent) {
5762                    if (rec.key.requestIntent != null) {
5763                        rec.key.requestIntent.replaceExtras(intents != null ?
5764                                intents[intents.length - 1] : null);
5765                    }
5766                    if (intents != null) {
5767                        intents[intents.length-1] = rec.key.requestIntent;
5768                        rec.key.allIntents = intents;
5769                        rec.key.allResolvedTypes = resolvedTypes;
5770                    } else {
5771                        rec.key.allIntents = null;
5772                        rec.key.allResolvedTypes = null;
5773                    }
5774                }
5775                return rec;
5776            }
5777            rec.canceled = true;
5778            mIntentSenderRecords.remove(key);
5779        }
5780        if (noCreate) {
5781            return rec;
5782        }
5783        rec = new PendingIntentRecord(this, key, callingUid);
5784        mIntentSenderRecords.put(key, rec.ref);
5785        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5786            if (activity.pendingResults == null) {
5787                activity.pendingResults
5788                        = new HashSet<WeakReference<PendingIntentRecord>>();
5789            }
5790            activity.pendingResults.add(rec.ref);
5791        }
5792        return rec;
5793    }
5794
5795    @Override
5796    public void cancelIntentSender(IIntentSender sender) {
5797        if (!(sender instanceof PendingIntentRecord)) {
5798            return;
5799        }
5800        synchronized(this) {
5801            PendingIntentRecord rec = (PendingIntentRecord)sender;
5802            try {
5803                int uid = AppGlobals.getPackageManager()
5804                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5805                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5806                    String msg = "Permission Denial: cancelIntentSender() from pid="
5807                        + Binder.getCallingPid()
5808                        + ", uid=" + Binder.getCallingUid()
5809                        + " is not allowed to cancel packges "
5810                        + rec.key.packageName;
5811                    Slog.w(TAG, msg);
5812                    throw new SecurityException(msg);
5813                }
5814            } catch (RemoteException e) {
5815                throw new SecurityException(e);
5816            }
5817            cancelIntentSenderLocked(rec, true);
5818        }
5819    }
5820
5821    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5822        rec.canceled = true;
5823        mIntentSenderRecords.remove(rec.key);
5824        if (cleanActivity && rec.key.activity != null) {
5825            rec.key.activity.pendingResults.remove(rec.ref);
5826        }
5827    }
5828
5829    @Override
5830    public String getPackageForIntentSender(IIntentSender pendingResult) {
5831        if (!(pendingResult instanceof PendingIntentRecord)) {
5832            return null;
5833        }
5834        try {
5835            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5836            return res.key.packageName;
5837        } catch (ClassCastException e) {
5838        }
5839        return null;
5840    }
5841
5842    @Override
5843    public int getUidForIntentSender(IIntentSender sender) {
5844        if (sender instanceof PendingIntentRecord) {
5845            try {
5846                PendingIntentRecord res = (PendingIntentRecord)sender;
5847                return res.uid;
5848            } catch (ClassCastException e) {
5849            }
5850        }
5851        return -1;
5852    }
5853
5854    @Override
5855    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5856        if (!(pendingResult instanceof PendingIntentRecord)) {
5857            return false;
5858        }
5859        try {
5860            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5861            if (res.key.allIntents == null) {
5862                return false;
5863            }
5864            for (int i=0; i<res.key.allIntents.length; i++) {
5865                Intent intent = res.key.allIntents[i];
5866                if (intent.getPackage() != null && intent.getComponent() != null) {
5867                    return false;
5868                }
5869            }
5870            return true;
5871        } catch (ClassCastException e) {
5872        }
5873        return false;
5874    }
5875
5876    @Override
5877    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5878        if (!(pendingResult instanceof PendingIntentRecord)) {
5879            return false;
5880        }
5881        try {
5882            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5883            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5884                return true;
5885            }
5886            return false;
5887        } catch (ClassCastException e) {
5888        }
5889        return false;
5890    }
5891
5892    @Override
5893    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5894        if (!(pendingResult instanceof PendingIntentRecord)) {
5895            return null;
5896        }
5897        try {
5898            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5899            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5900        } catch (ClassCastException e) {
5901        }
5902        return null;
5903    }
5904
5905    @Override
5906    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5907        if (!(pendingResult instanceof PendingIntentRecord)) {
5908            return null;
5909        }
5910        try {
5911            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5912            Intent intent = res.key.requestIntent;
5913            if (intent != null) {
5914                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5915                        || res.lastTagPrefix.equals(prefix))) {
5916                    return res.lastTag;
5917                }
5918                res.lastTagPrefix = prefix;
5919                StringBuilder sb = new StringBuilder(128);
5920                if (prefix != null) {
5921                    sb.append(prefix);
5922                }
5923                if (intent.getAction() != null) {
5924                    sb.append(intent.getAction());
5925                } else if (intent.getComponent() != null) {
5926                    intent.getComponent().appendShortString(sb);
5927                } else {
5928                    sb.append("?");
5929                }
5930                return res.lastTag = sb.toString();
5931            }
5932        } catch (ClassCastException e) {
5933        }
5934        return null;
5935    }
5936
5937    @Override
5938    public void setProcessLimit(int max) {
5939        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5940                "setProcessLimit()");
5941        synchronized (this) {
5942            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5943            mProcessLimitOverride = max;
5944        }
5945        trimApplications();
5946    }
5947
5948    @Override
5949    public int getProcessLimit() {
5950        synchronized (this) {
5951            return mProcessLimitOverride;
5952        }
5953    }
5954
5955    void foregroundTokenDied(ForegroundToken token) {
5956        synchronized (ActivityManagerService.this) {
5957            synchronized (mPidsSelfLocked) {
5958                ForegroundToken cur
5959                    = mForegroundProcesses.get(token.pid);
5960                if (cur != token) {
5961                    return;
5962                }
5963                mForegroundProcesses.remove(token.pid);
5964                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5965                if (pr == null) {
5966                    return;
5967                }
5968                pr.forcingToForeground = null;
5969                updateProcessForegroundLocked(pr, false, false);
5970            }
5971            updateOomAdjLocked();
5972        }
5973    }
5974
5975    @Override
5976    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5977        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5978                "setProcessForeground()");
5979        synchronized(this) {
5980            boolean changed = false;
5981
5982            synchronized (mPidsSelfLocked) {
5983                ProcessRecord pr = mPidsSelfLocked.get(pid);
5984                if (pr == null && isForeground) {
5985                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5986                    return;
5987                }
5988                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5989                if (oldToken != null) {
5990                    oldToken.token.unlinkToDeath(oldToken, 0);
5991                    mForegroundProcesses.remove(pid);
5992                    if (pr != null) {
5993                        pr.forcingToForeground = null;
5994                    }
5995                    changed = true;
5996                }
5997                if (isForeground && token != null) {
5998                    ForegroundToken newToken = new ForegroundToken() {
5999                        @Override
6000                        public void binderDied() {
6001                            foregroundTokenDied(this);
6002                        }
6003                    };
6004                    newToken.pid = pid;
6005                    newToken.token = token;
6006                    try {
6007                        token.linkToDeath(newToken, 0);
6008                        mForegroundProcesses.put(pid, newToken);
6009                        pr.forcingToForeground = token;
6010                        changed = true;
6011                    } catch (RemoteException e) {
6012                        // If the process died while doing this, we will later
6013                        // do the cleanup with the process death link.
6014                    }
6015                }
6016            }
6017
6018            if (changed) {
6019                updateOomAdjLocked();
6020            }
6021        }
6022    }
6023
6024    // =========================================================
6025    // PERMISSIONS
6026    // =========================================================
6027
6028    static class PermissionController extends IPermissionController.Stub {
6029        ActivityManagerService mActivityManagerService;
6030        PermissionController(ActivityManagerService activityManagerService) {
6031            mActivityManagerService = activityManagerService;
6032        }
6033
6034        @Override
6035        public boolean checkPermission(String permission, int pid, int uid) {
6036            return mActivityManagerService.checkPermission(permission, pid,
6037                    uid) == PackageManager.PERMISSION_GRANTED;
6038        }
6039    }
6040
6041    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6042        @Override
6043        public int checkComponentPermission(String permission, int pid, int uid,
6044                int owningUid, boolean exported) {
6045            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6046                    owningUid, exported);
6047        }
6048
6049        @Override
6050        public Object getAMSLock() {
6051            return ActivityManagerService.this;
6052        }
6053    }
6054
6055    /**
6056     * This can be called with or without the global lock held.
6057     */
6058    int checkComponentPermission(String permission, int pid, int uid,
6059            int owningUid, boolean exported) {
6060        // We might be performing an operation on behalf of an indirect binder
6061        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6062        // client identity accordingly before proceeding.
6063        Identity tlsIdentity = sCallerIdentity.get();
6064        if (tlsIdentity != null) {
6065            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6066                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6067            uid = tlsIdentity.uid;
6068            pid = tlsIdentity.pid;
6069        }
6070
6071        if (pid == MY_PID) {
6072            return PackageManager.PERMISSION_GRANTED;
6073        }
6074
6075        return ActivityManager.checkComponentPermission(permission, uid,
6076                owningUid, exported);
6077    }
6078
6079    /**
6080     * As the only public entry point for permissions checking, this method
6081     * can enforce the semantic that requesting a check on a null global
6082     * permission is automatically denied.  (Internally a null permission
6083     * string is used when calling {@link #checkComponentPermission} in cases
6084     * when only uid-based security is needed.)
6085     *
6086     * This can be called with or without the global lock held.
6087     */
6088    @Override
6089    public int checkPermission(String permission, int pid, int uid) {
6090        if (permission == null) {
6091            return PackageManager.PERMISSION_DENIED;
6092        }
6093        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6094    }
6095
6096    /**
6097     * Binder IPC calls go through the public entry point.
6098     * This can be called with or without the global lock held.
6099     */
6100    int checkCallingPermission(String permission) {
6101        return checkPermission(permission,
6102                Binder.getCallingPid(),
6103                UserHandle.getAppId(Binder.getCallingUid()));
6104    }
6105
6106    /**
6107     * This can be called with or without the global lock held.
6108     */
6109    void enforceCallingPermission(String permission, String func) {
6110        if (checkCallingPermission(permission)
6111                == PackageManager.PERMISSION_GRANTED) {
6112            return;
6113        }
6114
6115        String msg = "Permission Denial: " + func + " from pid="
6116                + Binder.getCallingPid()
6117                + ", uid=" + Binder.getCallingUid()
6118                + " requires " + permission;
6119        Slog.w(TAG, msg);
6120        throw new SecurityException(msg);
6121    }
6122
6123    /**
6124     * Determine if UID is holding permissions required to access {@link Uri} in
6125     * the given {@link ProviderInfo}. Final permission checking is always done
6126     * in {@link ContentProvider}.
6127     */
6128    private final boolean checkHoldingPermissionsLocked(
6129            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6130        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6131                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6132        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6133            return false;
6134        }
6135        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6136    }
6137
6138    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6139            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6140        if (pi.applicationInfo.uid == uid) {
6141            return true;
6142        } else if (!pi.exported) {
6143            return false;
6144        }
6145
6146        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6147        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6148        try {
6149            // check if target holds top-level <provider> permissions
6150            if (!readMet && pi.readPermission != null && considerUidPermissions
6151                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6152                readMet = true;
6153            }
6154            if (!writeMet && pi.writePermission != null && considerUidPermissions
6155                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6156                writeMet = true;
6157            }
6158
6159            // track if unprotected read/write is allowed; any denied
6160            // <path-permission> below removes this ability
6161            boolean allowDefaultRead = pi.readPermission == null;
6162            boolean allowDefaultWrite = pi.writePermission == null;
6163
6164            // check if target holds any <path-permission> that match uri
6165            final PathPermission[] pps = pi.pathPermissions;
6166            if (pps != null) {
6167                final String path = grantUri.uri.getPath();
6168                int i = pps.length;
6169                while (i > 0 && (!readMet || !writeMet)) {
6170                    i--;
6171                    PathPermission pp = pps[i];
6172                    if (pp.match(path)) {
6173                        if (!readMet) {
6174                            final String pprperm = pp.getReadPermission();
6175                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6176                                    + pprperm + " for " + pp.getPath()
6177                                    + ": match=" + pp.match(path)
6178                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6179                            if (pprperm != null) {
6180                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6181                                        == PERMISSION_GRANTED) {
6182                                    readMet = true;
6183                                } else {
6184                                    allowDefaultRead = false;
6185                                }
6186                            }
6187                        }
6188                        if (!writeMet) {
6189                            final String ppwperm = pp.getWritePermission();
6190                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6191                                    + ppwperm + " for " + pp.getPath()
6192                                    + ": match=" + pp.match(path)
6193                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6194                            if (ppwperm != null) {
6195                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6196                                        == PERMISSION_GRANTED) {
6197                                    writeMet = true;
6198                                } else {
6199                                    allowDefaultWrite = false;
6200                                }
6201                            }
6202                        }
6203                    }
6204                }
6205            }
6206
6207            // grant unprotected <provider> read/write, if not blocked by
6208            // <path-permission> above
6209            if (allowDefaultRead) readMet = true;
6210            if (allowDefaultWrite) writeMet = true;
6211
6212        } catch (RemoteException e) {
6213            return false;
6214        }
6215
6216        return readMet && writeMet;
6217    }
6218
6219    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6220        ProviderInfo pi = null;
6221        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6222        if (cpr != null) {
6223            pi = cpr.info;
6224        } else {
6225            try {
6226                pi = AppGlobals.getPackageManager().resolveContentProvider(
6227                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6228            } catch (RemoteException ex) {
6229            }
6230        }
6231        return pi;
6232    }
6233
6234    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6235        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6236        if (targetUris != null) {
6237            return targetUris.get(grantUri);
6238        }
6239        return null;
6240    }
6241
6242    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6243            String targetPkg, int targetUid, GrantUri grantUri) {
6244        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6245        if (targetUris == null) {
6246            targetUris = Maps.newArrayMap();
6247            mGrantedUriPermissions.put(targetUid, targetUris);
6248        }
6249
6250        UriPermission perm = targetUris.get(grantUri);
6251        if (perm == null) {
6252            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6253            targetUris.put(grantUri, perm);
6254        }
6255
6256        return perm;
6257    }
6258
6259    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6260            final int modeFlags) {
6261        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6262        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6263                : UriPermission.STRENGTH_OWNED;
6264
6265        // Root gets to do everything.
6266        if (uid == 0) {
6267            return true;
6268        }
6269
6270        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6271        if (perms == null) return false;
6272
6273        // First look for exact match
6274        final UriPermission exactPerm = perms.get(grantUri);
6275        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6276            return true;
6277        }
6278
6279        // No exact match, look for prefixes
6280        final int N = perms.size();
6281        for (int i = 0; i < N; i++) {
6282            final UriPermission perm = perms.valueAt(i);
6283            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6284                    && perm.getStrength(modeFlags) >= minStrength) {
6285                return true;
6286            }
6287        }
6288
6289        return false;
6290    }
6291
6292    @Override
6293    public int checkUriPermission(Uri uri, int pid, int uid,
6294            final int modeFlags, int userId) {
6295        enforceNotIsolatedCaller("checkUriPermission");
6296
6297        // Another redirected-binder-call permissions check as in
6298        // {@link checkComponentPermission}.
6299        Identity tlsIdentity = sCallerIdentity.get();
6300        if (tlsIdentity != null) {
6301            uid = tlsIdentity.uid;
6302            pid = tlsIdentity.pid;
6303        }
6304
6305        // Our own process gets to do everything.
6306        if (pid == MY_PID) {
6307            return PackageManager.PERMISSION_GRANTED;
6308        }
6309        synchronized (this) {
6310            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6311                    ? PackageManager.PERMISSION_GRANTED
6312                    : PackageManager.PERMISSION_DENIED;
6313        }
6314    }
6315
6316    /**
6317     * Check if the targetPkg can be granted permission to access uri by
6318     * the callingUid using the given modeFlags.  Throws a security exception
6319     * if callingUid is not allowed to do this.  Returns the uid of the target
6320     * if the URI permission grant should be performed; returns -1 if it is not
6321     * needed (for example targetPkg already has permission to access the URI).
6322     * If you already know the uid of the target, you can supply it in
6323     * lastTargetUid else set that to -1.
6324     */
6325    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6326            final int modeFlags, int lastTargetUid) {
6327        if (!Intent.isAccessUriMode(modeFlags)) {
6328            return -1;
6329        }
6330
6331        if (targetPkg != null) {
6332            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6333                    "Checking grant " + targetPkg + " permission to " + grantUri);
6334        }
6335
6336        final IPackageManager pm = AppGlobals.getPackageManager();
6337
6338        // If this is not a content: uri, we can't do anything with it.
6339        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6340            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6341                    "Can't grant URI permission for non-content URI: " + grantUri);
6342            return -1;
6343        }
6344
6345        final String authority = grantUri.uri.getAuthority();
6346        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6347        if (pi == null) {
6348            Slog.w(TAG, "No content provider found for permission check: " +
6349                    grantUri.uri.toSafeString());
6350            return -1;
6351        }
6352
6353        int targetUid = lastTargetUid;
6354        if (targetUid < 0 && targetPkg != null) {
6355            try {
6356                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6357                if (targetUid < 0) {
6358                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6359                            "Can't grant URI permission no uid for: " + targetPkg);
6360                    return -1;
6361                }
6362            } catch (RemoteException ex) {
6363                return -1;
6364            }
6365        }
6366
6367        if (targetUid >= 0) {
6368            // First...  does the target actually need this permission?
6369            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6370                // No need to grant the target this permission.
6371                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6372                        "Target " + targetPkg + " already has full permission to " + grantUri);
6373                return -1;
6374            }
6375        } else {
6376            // First...  there is no target package, so can anyone access it?
6377            boolean allowed = pi.exported;
6378            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6379                if (pi.readPermission != null) {
6380                    allowed = false;
6381                }
6382            }
6383            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6384                if (pi.writePermission != null) {
6385                    allowed = false;
6386                }
6387            }
6388            if (allowed) {
6389                return -1;
6390            }
6391        }
6392
6393        /* There is a special cross user grant if:
6394         * - The target is on another user.
6395         * - Apps on the current user can access the uri without any uid permissions.
6396         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6397         * grant uri permissions.
6398         */
6399        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6400                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6401                modeFlags, false /*without considering the uid permissions*/);
6402
6403        // Second...  is the provider allowing granting of URI permissions?
6404        if (!specialCrossUserGrant) {
6405            if (!pi.grantUriPermissions) {
6406                throw new SecurityException("Provider " + pi.packageName
6407                        + "/" + pi.name
6408                        + " does not allow granting of Uri permissions (uri "
6409                        + grantUri + ")");
6410            }
6411            if (pi.uriPermissionPatterns != null) {
6412                final int N = pi.uriPermissionPatterns.length;
6413                boolean allowed = false;
6414                for (int i=0; i<N; i++) {
6415                    if (pi.uriPermissionPatterns[i] != null
6416                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6417                        allowed = true;
6418                        break;
6419                    }
6420                }
6421                if (!allowed) {
6422                    throw new SecurityException("Provider " + pi.packageName
6423                            + "/" + pi.name
6424                            + " does not allow granting of permission to path of Uri "
6425                            + grantUri);
6426                }
6427            }
6428        }
6429
6430        // Third...  does the caller itself have permission to access
6431        // this uri?
6432        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6433            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6434                // Require they hold a strong enough Uri permission
6435                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6436                    throw new SecurityException("Uid " + callingUid
6437                            + " does not have permission to uri " + grantUri);
6438                }
6439            }
6440        }
6441        return targetUid;
6442    }
6443
6444    @Override
6445    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6446            final int modeFlags, int userId) {
6447        enforceNotIsolatedCaller("checkGrantUriPermission");
6448        synchronized(this) {
6449            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6450                    new GrantUri(userId, uri, false), modeFlags, -1);
6451        }
6452    }
6453
6454    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6455            final int modeFlags, UriPermissionOwner owner) {
6456        if (!Intent.isAccessUriMode(modeFlags)) {
6457            return;
6458        }
6459
6460        // So here we are: the caller has the assumed permission
6461        // to the uri, and the target doesn't.  Let's now give this to
6462        // the target.
6463
6464        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6465                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6466
6467        final String authority = grantUri.uri.getAuthority();
6468        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6469        if (pi == null) {
6470            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6471            return;
6472        }
6473
6474        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6475            grantUri.prefix = true;
6476        }
6477        final UriPermission perm = findOrCreateUriPermissionLocked(
6478                pi.packageName, targetPkg, targetUid, grantUri);
6479        perm.grantModes(modeFlags, owner);
6480    }
6481
6482    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6483            final int modeFlags, UriPermissionOwner owner) {
6484        if (targetPkg == null) {
6485            throw new NullPointerException("targetPkg");
6486        }
6487
6488        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6489                -1);
6490        if (targetUid < 0) {
6491            return;
6492        }
6493
6494        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6495                owner);
6496    }
6497
6498    static class NeededUriGrants extends ArrayList<GrantUri> {
6499        final String targetPkg;
6500        final int targetUid;
6501        final int flags;
6502
6503        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6504            this.targetPkg = targetPkg;
6505            this.targetUid = targetUid;
6506            this.flags = flags;
6507        }
6508    }
6509
6510    /**
6511     * Like checkGrantUriPermissionLocked, but takes an Intent.
6512     */
6513    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6514            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6515        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6516                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6517                + " clip=" + (intent != null ? intent.getClipData() : null)
6518                + " from " + intent + "; flags=0x"
6519                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6520
6521        if (targetPkg == null) {
6522            throw new NullPointerException("targetPkg");
6523        }
6524
6525        if (intent == null) {
6526            return null;
6527        }
6528        Uri data = intent.getData();
6529        ClipData clip = intent.getClipData();
6530        if (data == null && clip == null) {
6531            return null;
6532        }
6533        final IPackageManager pm = AppGlobals.getPackageManager();
6534        int targetUid;
6535        if (needed != null) {
6536            targetUid = needed.targetUid;
6537        } else {
6538            try {
6539                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6540            } catch (RemoteException ex) {
6541                return null;
6542            }
6543            if (targetUid < 0) {
6544                if (DEBUG_URI_PERMISSION) {
6545                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6546                            + " on user " + targetUserId);
6547                }
6548                return null;
6549            }
6550        }
6551        if (data != null) {
6552            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6553            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6554                    targetUid);
6555            if (targetUid > 0) {
6556                if (needed == null) {
6557                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6558                }
6559                needed.add(grantUri);
6560            }
6561        }
6562        if (clip != null) {
6563            for (int i=0; i<clip.getItemCount(); i++) {
6564                Uri uri = clip.getItemAt(i).getUri();
6565                if (uri != null) {
6566                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6567                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6568                            targetUid);
6569                    if (targetUid > 0) {
6570                        if (needed == null) {
6571                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6572                        }
6573                        needed.add(grantUri);
6574                    }
6575                } else {
6576                    Intent clipIntent = clip.getItemAt(i).getIntent();
6577                    if (clipIntent != null) {
6578                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6579                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6580                        if (newNeeded != null) {
6581                            needed = newNeeded;
6582                        }
6583                    }
6584                }
6585            }
6586        }
6587
6588        return needed;
6589    }
6590
6591    /**
6592     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6593     */
6594    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6595            UriPermissionOwner owner) {
6596        if (needed != null) {
6597            for (int i=0; i<needed.size(); i++) {
6598                GrantUri grantUri = needed.get(i);
6599                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6600                        grantUri, needed.flags, owner);
6601            }
6602        }
6603    }
6604
6605    void grantUriPermissionFromIntentLocked(int callingUid,
6606            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6607        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6608                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6609        if (needed == null) {
6610            return;
6611        }
6612
6613        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6614    }
6615
6616    @Override
6617    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6618            final int modeFlags, int userId) {
6619        enforceNotIsolatedCaller("grantUriPermission");
6620        GrantUri grantUri = new GrantUri(userId, uri, false);
6621        synchronized(this) {
6622            final ProcessRecord r = getRecordForAppLocked(caller);
6623            if (r == null) {
6624                throw new SecurityException("Unable to find app for caller "
6625                        + caller
6626                        + " when granting permission to uri " + grantUri);
6627            }
6628            if (targetPkg == null) {
6629                throw new IllegalArgumentException("null target");
6630            }
6631            if (grantUri == null) {
6632                throw new IllegalArgumentException("null uri");
6633            }
6634
6635            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6636                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6637                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6638                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6639
6640            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6641        }
6642    }
6643
6644    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6645        if (perm.modeFlags == 0) {
6646            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6647                    perm.targetUid);
6648            if (perms != null) {
6649                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6650                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6651
6652                perms.remove(perm.uri);
6653                if (perms.isEmpty()) {
6654                    mGrantedUriPermissions.remove(perm.targetUid);
6655                }
6656            }
6657        }
6658    }
6659
6660    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6661        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6662
6663        final IPackageManager pm = AppGlobals.getPackageManager();
6664        final String authority = grantUri.uri.getAuthority();
6665        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6666        if (pi == null) {
6667            Slog.w(TAG, "No content provider found for permission revoke: "
6668                    + grantUri.toSafeString());
6669            return;
6670        }
6671
6672        // Does the caller have this permission on the URI?
6673        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6674            // Right now, if you are not the original owner of the permission,
6675            // you are not allowed to revoke it.
6676            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6677                throw new SecurityException("Uid " + callingUid
6678                        + " does not have permission to uri " + grantUri);
6679            //}
6680        }
6681
6682        boolean persistChanged = false;
6683
6684        // Go through all of the permissions and remove any that match.
6685        int N = mGrantedUriPermissions.size();
6686        for (int i = 0; i < N; i++) {
6687            final int targetUid = mGrantedUriPermissions.keyAt(i);
6688            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6689
6690            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6691                final UriPermission perm = it.next();
6692                if (perm.uri.sourceUserId == grantUri.sourceUserId
6693                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6694                    if (DEBUG_URI_PERMISSION)
6695                        Slog.v(TAG,
6696                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6697                    persistChanged |= perm.revokeModes(
6698                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6699                    if (perm.modeFlags == 0) {
6700                        it.remove();
6701                    }
6702                }
6703            }
6704
6705            if (perms.isEmpty()) {
6706                mGrantedUriPermissions.remove(targetUid);
6707                N--;
6708                i--;
6709            }
6710        }
6711
6712        if (persistChanged) {
6713            schedulePersistUriGrants();
6714        }
6715    }
6716
6717    @Override
6718    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6719            int userId) {
6720        enforceNotIsolatedCaller("revokeUriPermission");
6721        synchronized(this) {
6722            final ProcessRecord r = getRecordForAppLocked(caller);
6723            if (r == null) {
6724                throw new SecurityException("Unable to find app for caller "
6725                        + caller
6726                        + " when revoking permission to uri " + uri);
6727            }
6728            if (uri == null) {
6729                Slog.w(TAG, "revokeUriPermission: null uri");
6730                return;
6731            }
6732
6733            if (!Intent.isAccessUriMode(modeFlags)) {
6734                return;
6735            }
6736
6737            final IPackageManager pm = AppGlobals.getPackageManager();
6738            final String authority = uri.getAuthority();
6739            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6740            if (pi == null) {
6741                Slog.w(TAG, "No content provider found for permission revoke: "
6742                        + uri.toSafeString());
6743                return;
6744            }
6745
6746            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6747        }
6748    }
6749
6750    /**
6751     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6752     * given package.
6753     *
6754     * @param packageName Package name to match, or {@code null} to apply to all
6755     *            packages.
6756     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6757     *            to all users.
6758     * @param persistable If persistable grants should be removed.
6759     */
6760    private void removeUriPermissionsForPackageLocked(
6761            String packageName, int userHandle, boolean persistable) {
6762        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6763            throw new IllegalArgumentException("Must narrow by either package or user");
6764        }
6765
6766        boolean persistChanged = false;
6767
6768        int N = mGrantedUriPermissions.size();
6769        for (int i = 0; i < N; i++) {
6770            final int targetUid = mGrantedUriPermissions.keyAt(i);
6771            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6772
6773            // Only inspect grants matching user
6774            if (userHandle == UserHandle.USER_ALL
6775                    || userHandle == UserHandle.getUserId(targetUid)) {
6776                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6777                    final UriPermission perm = it.next();
6778
6779                    // Only inspect grants matching package
6780                    if (packageName == null || perm.sourcePkg.equals(packageName)
6781                            || perm.targetPkg.equals(packageName)) {
6782                        persistChanged |= perm.revokeModes(
6783                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6784
6785                        // Only remove when no modes remain; any persisted grants
6786                        // will keep this alive.
6787                        if (perm.modeFlags == 0) {
6788                            it.remove();
6789                        }
6790                    }
6791                }
6792
6793                if (perms.isEmpty()) {
6794                    mGrantedUriPermissions.remove(targetUid);
6795                    N--;
6796                    i--;
6797                }
6798            }
6799        }
6800
6801        if (persistChanged) {
6802            schedulePersistUriGrants();
6803        }
6804    }
6805
6806    @Override
6807    public IBinder newUriPermissionOwner(String name) {
6808        enforceNotIsolatedCaller("newUriPermissionOwner");
6809        synchronized(this) {
6810            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6811            return owner.getExternalTokenLocked();
6812        }
6813    }
6814
6815    @Override
6816    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6817            final int modeFlags, int userId) {
6818        synchronized(this) {
6819            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6820            if (owner == null) {
6821                throw new IllegalArgumentException("Unknown owner: " + token);
6822            }
6823            if (fromUid != Binder.getCallingUid()) {
6824                if (Binder.getCallingUid() != Process.myUid()) {
6825                    // Only system code can grant URI permissions on behalf
6826                    // of other users.
6827                    throw new SecurityException("nice try");
6828                }
6829            }
6830            if (targetPkg == null) {
6831                throw new IllegalArgumentException("null target");
6832            }
6833            if (uri == null) {
6834                throw new IllegalArgumentException("null uri");
6835            }
6836
6837            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6838                    modeFlags, owner);
6839        }
6840    }
6841
6842    @Override
6843    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6844        synchronized(this) {
6845            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6846            if (owner == null) {
6847                throw new IllegalArgumentException("Unknown owner: " + token);
6848            }
6849
6850            if (uri == null) {
6851                owner.removeUriPermissionsLocked(mode);
6852            } else {
6853                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6854            }
6855        }
6856    }
6857
6858    private void schedulePersistUriGrants() {
6859        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6860            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6861                    10 * DateUtils.SECOND_IN_MILLIS);
6862        }
6863    }
6864
6865    private void writeGrantedUriPermissions() {
6866        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6867
6868        // Snapshot permissions so we can persist without lock
6869        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6870        synchronized (this) {
6871            final int size = mGrantedUriPermissions.size();
6872            for (int i = 0; i < size; i++) {
6873                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6874                for (UriPermission perm : perms.values()) {
6875                    if (perm.persistedModeFlags != 0) {
6876                        persist.add(perm.snapshot());
6877                    }
6878                }
6879            }
6880        }
6881
6882        FileOutputStream fos = null;
6883        try {
6884            fos = mGrantFile.startWrite();
6885
6886            XmlSerializer out = new FastXmlSerializer();
6887            out.setOutput(fos, "utf-8");
6888            out.startDocument(null, true);
6889            out.startTag(null, TAG_URI_GRANTS);
6890            for (UriPermission.Snapshot perm : persist) {
6891                out.startTag(null, TAG_URI_GRANT);
6892                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6893                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6894                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6895                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6896                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6897                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6898                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6899                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6900                out.endTag(null, TAG_URI_GRANT);
6901            }
6902            out.endTag(null, TAG_URI_GRANTS);
6903            out.endDocument();
6904
6905            mGrantFile.finishWrite(fos);
6906        } catch (IOException e) {
6907            if (fos != null) {
6908                mGrantFile.failWrite(fos);
6909            }
6910        }
6911    }
6912
6913    private void readGrantedUriPermissionsLocked() {
6914        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6915
6916        final long now = System.currentTimeMillis();
6917
6918        FileInputStream fis = null;
6919        try {
6920            fis = mGrantFile.openRead();
6921            final XmlPullParser in = Xml.newPullParser();
6922            in.setInput(fis, null);
6923
6924            int type;
6925            while ((type = in.next()) != END_DOCUMENT) {
6926                final String tag = in.getName();
6927                if (type == START_TAG) {
6928                    if (TAG_URI_GRANT.equals(tag)) {
6929                        final int sourceUserId;
6930                        final int targetUserId;
6931                        final int userHandle = readIntAttribute(in,
6932                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6933                        if (userHandle != UserHandle.USER_NULL) {
6934                            // For backwards compatibility.
6935                            sourceUserId = userHandle;
6936                            targetUserId = userHandle;
6937                        } else {
6938                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6939                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6940                        }
6941                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6942                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6943                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6944                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6945                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6946                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6947
6948                        // Sanity check that provider still belongs to source package
6949                        final ProviderInfo pi = getProviderInfoLocked(
6950                                uri.getAuthority(), sourceUserId);
6951                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6952                            int targetUid = -1;
6953                            try {
6954                                targetUid = AppGlobals.getPackageManager()
6955                                        .getPackageUid(targetPkg, targetUserId);
6956                            } catch (RemoteException e) {
6957                            }
6958                            if (targetUid != -1) {
6959                                final UriPermission perm = findOrCreateUriPermissionLocked(
6960                                        sourcePkg, targetPkg, targetUid,
6961                                        new GrantUri(sourceUserId, uri, prefix));
6962                                perm.initPersistedModes(modeFlags, createdTime);
6963                            }
6964                        } else {
6965                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6966                                    + " but instead found " + pi);
6967                        }
6968                    }
6969                }
6970            }
6971        } catch (FileNotFoundException e) {
6972            // Missing grants is okay
6973        } catch (IOException e) {
6974            Log.wtf(TAG, "Failed reading Uri grants", e);
6975        } catch (XmlPullParserException e) {
6976            Log.wtf(TAG, "Failed reading Uri grants", e);
6977        } finally {
6978            IoUtils.closeQuietly(fis);
6979        }
6980    }
6981
6982    @Override
6983    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6984        enforceNotIsolatedCaller("takePersistableUriPermission");
6985
6986        Preconditions.checkFlagsArgument(modeFlags,
6987                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6988
6989        synchronized (this) {
6990            final int callingUid = Binder.getCallingUid();
6991            boolean persistChanged = false;
6992            GrantUri grantUri = new GrantUri(userId, uri, false);
6993
6994            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6995                    new GrantUri(userId, uri, false));
6996            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6997                    new GrantUri(userId, uri, true));
6998
6999            final boolean exactValid = (exactPerm != null)
7000                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7001            final boolean prefixValid = (prefixPerm != null)
7002                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7003
7004            if (!(exactValid || prefixValid)) {
7005                throw new SecurityException("No persistable permission grants found for UID "
7006                        + callingUid + " and Uri " + grantUri.toSafeString());
7007            }
7008
7009            if (exactValid) {
7010                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7011            }
7012            if (prefixValid) {
7013                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7014            }
7015
7016            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7017
7018            if (persistChanged) {
7019                schedulePersistUriGrants();
7020            }
7021        }
7022    }
7023
7024    @Override
7025    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7026        enforceNotIsolatedCaller("releasePersistableUriPermission");
7027
7028        Preconditions.checkFlagsArgument(modeFlags,
7029                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7030
7031        synchronized (this) {
7032            final int callingUid = Binder.getCallingUid();
7033            boolean persistChanged = false;
7034
7035            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7036                    new GrantUri(userId, uri, false));
7037            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7038                    new GrantUri(userId, uri, true));
7039            if (exactPerm == null && prefixPerm == null) {
7040                throw new SecurityException("No permission grants found for UID " + callingUid
7041                        + " and Uri " + uri.toSafeString());
7042            }
7043
7044            if (exactPerm != null) {
7045                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7046                removeUriPermissionIfNeededLocked(exactPerm);
7047            }
7048            if (prefixPerm != null) {
7049                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7050                removeUriPermissionIfNeededLocked(prefixPerm);
7051            }
7052
7053            if (persistChanged) {
7054                schedulePersistUriGrants();
7055            }
7056        }
7057    }
7058
7059    /**
7060     * Prune any older {@link UriPermission} for the given UID until outstanding
7061     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7062     *
7063     * @return if any mutations occured that require persisting.
7064     */
7065    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7066        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7067        if (perms == null) return false;
7068        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7069
7070        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7071        for (UriPermission perm : perms.values()) {
7072            if (perm.persistedModeFlags != 0) {
7073                persisted.add(perm);
7074            }
7075        }
7076
7077        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7078        if (trimCount <= 0) return false;
7079
7080        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7081        for (int i = 0; i < trimCount; i++) {
7082            final UriPermission perm = persisted.get(i);
7083
7084            if (DEBUG_URI_PERMISSION) {
7085                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7086            }
7087
7088            perm.releasePersistableModes(~0);
7089            removeUriPermissionIfNeededLocked(perm);
7090        }
7091
7092        return true;
7093    }
7094
7095    @Override
7096    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7097            String packageName, boolean incoming) {
7098        enforceNotIsolatedCaller("getPersistedUriPermissions");
7099        Preconditions.checkNotNull(packageName, "packageName");
7100
7101        final int callingUid = Binder.getCallingUid();
7102        final IPackageManager pm = AppGlobals.getPackageManager();
7103        try {
7104            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7105            if (packageUid != callingUid) {
7106                throw new SecurityException(
7107                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7108            }
7109        } catch (RemoteException e) {
7110            throw new SecurityException("Failed to verify package name ownership");
7111        }
7112
7113        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7114        synchronized (this) {
7115            if (incoming) {
7116                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7117                        callingUid);
7118                if (perms == null) {
7119                    Slog.w(TAG, "No permission grants found for " + packageName);
7120                } else {
7121                    for (UriPermission perm : perms.values()) {
7122                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7123                            result.add(perm.buildPersistedPublicApiObject());
7124                        }
7125                    }
7126                }
7127            } else {
7128                final int size = mGrantedUriPermissions.size();
7129                for (int i = 0; i < size; i++) {
7130                    final ArrayMap<GrantUri, UriPermission> perms =
7131                            mGrantedUriPermissions.valueAt(i);
7132                    for (UriPermission perm : perms.values()) {
7133                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7134                            result.add(perm.buildPersistedPublicApiObject());
7135                        }
7136                    }
7137                }
7138            }
7139        }
7140        return new ParceledListSlice<android.content.UriPermission>(result);
7141    }
7142
7143    @Override
7144    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7145        synchronized (this) {
7146            ProcessRecord app =
7147                who != null ? getRecordForAppLocked(who) : null;
7148            if (app == null) return;
7149
7150            Message msg = Message.obtain();
7151            msg.what = WAIT_FOR_DEBUGGER_MSG;
7152            msg.obj = app;
7153            msg.arg1 = waiting ? 1 : 0;
7154            mHandler.sendMessage(msg);
7155        }
7156    }
7157
7158    @Override
7159    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7160        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7161        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7162        outInfo.availMem = Process.getFreeMemory();
7163        outInfo.totalMem = Process.getTotalMemory();
7164        outInfo.threshold = homeAppMem;
7165        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7166        outInfo.hiddenAppThreshold = cachedAppMem;
7167        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7168                ProcessList.SERVICE_ADJ);
7169        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7170                ProcessList.VISIBLE_APP_ADJ);
7171        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7172                ProcessList.FOREGROUND_APP_ADJ);
7173    }
7174
7175    // =========================================================
7176    // TASK MANAGEMENT
7177    // =========================================================
7178
7179    @Override
7180    public List<IAppTask> getAppTasks() {
7181        final PackageManager pm = mContext.getPackageManager();
7182        int callingUid = Binder.getCallingUid();
7183        long ident = Binder.clearCallingIdentity();
7184
7185        // Compose the list of packages for this id to test against
7186        HashSet<String> packages = new HashSet<String>();
7187        String[] uidPackages = pm.getPackagesForUid(callingUid);
7188        for (int i = 0; i < uidPackages.length; i++) {
7189            packages.add(uidPackages[i]);
7190        }
7191
7192        synchronized(this) {
7193            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7194            try {
7195                if (localLOGV) Slog.v(TAG, "getAppTasks");
7196
7197                final int N = mRecentTasks.size();
7198                for (int i = 0; i < N; i++) {
7199                    TaskRecord tr = mRecentTasks.get(i);
7200                    // Skip tasks that are not created by the caller
7201                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7202                        ActivityManager.RecentTaskInfo taskInfo =
7203                                createRecentTaskInfoFromTaskRecord(tr);
7204                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7205                        list.add(taskImpl);
7206                    }
7207                }
7208            } finally {
7209                Binder.restoreCallingIdentity(ident);
7210            }
7211            return list;
7212        }
7213    }
7214
7215    @Override
7216    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7217        final int callingUid = Binder.getCallingUid();
7218        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7219
7220        synchronized(this) {
7221            if (localLOGV) Slog.v(
7222                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7223
7224            final boolean allowed = checkCallingPermission(
7225                    android.Manifest.permission.GET_TASKS)
7226                    == PackageManager.PERMISSION_GRANTED;
7227            if (!allowed) {
7228                Slog.w(TAG, "getTasks: caller " + callingUid
7229                        + " does not hold GET_TASKS; limiting output");
7230            }
7231
7232            // TODO: Improve with MRU list from all ActivityStacks.
7233            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7234        }
7235
7236        return list;
7237    }
7238
7239    TaskRecord getMostRecentTask() {
7240        return mRecentTasks.get(0);
7241    }
7242
7243    /**
7244     * Creates a new RecentTaskInfo from a TaskRecord.
7245     */
7246    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7247        // Update the task description to reflect any changes in the task stack
7248        tr.updateTaskDescription();
7249
7250        // Compose the recent task info
7251        ActivityManager.RecentTaskInfo rti
7252                = new ActivityManager.RecentTaskInfo();
7253        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7254        rti.persistentId = tr.taskId;
7255        rti.baseIntent = new Intent(tr.getBaseIntent());
7256        rti.origActivity = tr.origActivity;
7257        rti.description = tr.lastDescription;
7258        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7259        rti.userId = tr.userId;
7260        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7261        rti.lastActiveTime = tr.lastActiveTime;
7262        return rti;
7263    }
7264
7265    @Override
7266    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7267            int flags, int userId) {
7268        final int callingUid = Binder.getCallingUid();
7269        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7270                false, true, "getRecentTasks", null);
7271
7272        synchronized (this) {
7273            final boolean allowed = checkCallingPermission(
7274                    android.Manifest.permission.GET_TASKS)
7275                    == PackageManager.PERMISSION_GRANTED;
7276            if (!allowed) {
7277                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7278                        + " does not hold GET_TASKS; limiting output");
7279            }
7280            final boolean detailed = checkCallingPermission(
7281                    android.Manifest.permission.GET_DETAILED_TASKS)
7282                    == PackageManager.PERMISSION_GRANTED;
7283
7284            IPackageManager pm = AppGlobals.getPackageManager();
7285
7286            final int N = mRecentTasks.size();
7287            ArrayList<ActivityManager.RecentTaskInfo> res
7288                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7289                            maxNum < N ? maxNum : N);
7290
7291            final Set<Integer> includedUsers;
7292            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7293                includedUsers = getProfileIdsLocked(userId);
7294            } else {
7295                includedUsers = new HashSet<Integer>();
7296            }
7297            includedUsers.add(Integer.valueOf(userId));
7298            for (int i=0; i<N && maxNum > 0; i++) {
7299                TaskRecord tr = mRecentTasks.get(i);
7300                // Only add calling user or related users recent tasks
7301                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7302
7303                // Return the entry if desired by the caller.  We always return
7304                // the first entry, because callers always expect this to be the
7305                // foreground app.  We may filter others if the caller has
7306                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7307                // we should exclude the entry.
7308
7309                if (i == 0
7310                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7311                        || (tr.intent == null)
7312                        || ((tr.intent.getFlags()
7313                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7314                    if (!allowed) {
7315                        // If the caller doesn't have the GET_TASKS permission, then only
7316                        // allow them to see a small subset of tasks -- their own and home.
7317                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7318                            continue;
7319                        }
7320                    }
7321                    if (tr.intent != null &&
7322                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7323                            != 0 && tr.getTopActivity() == null) {
7324                        // Don't include auto remove tasks that are finished or finishing.
7325                        continue;
7326                    }
7327
7328                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7329                    if (!detailed) {
7330                        rti.baseIntent.replaceExtras((Bundle)null);
7331                    }
7332
7333                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7334                        // Check whether this activity is currently available.
7335                        try {
7336                            if (rti.origActivity != null) {
7337                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7338                                        == null) {
7339                                    continue;
7340                                }
7341                            } else if (rti.baseIntent != null) {
7342                                if (pm.queryIntentActivities(rti.baseIntent,
7343                                        null, 0, userId) == null) {
7344                                    continue;
7345                                }
7346                            }
7347                        } catch (RemoteException e) {
7348                            // Will never happen.
7349                        }
7350                    }
7351
7352                    res.add(rti);
7353                    maxNum--;
7354                }
7355            }
7356            return res;
7357        }
7358    }
7359
7360    private TaskRecord recentTaskForIdLocked(int id) {
7361        final int N = mRecentTasks.size();
7362            for (int i=0; i<N; i++) {
7363                TaskRecord tr = mRecentTasks.get(i);
7364                if (tr.taskId == id) {
7365                    return tr;
7366                }
7367            }
7368            return null;
7369    }
7370
7371    @Override
7372    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7373        synchronized (this) {
7374            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7375                    "getTaskThumbnail()");
7376            TaskRecord tr = recentTaskForIdLocked(id);
7377            if (tr != null) {
7378                return tr.getTaskThumbnailLocked();
7379            }
7380        }
7381        return null;
7382    }
7383
7384    @Override
7385    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7386        synchronized (this) {
7387            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7388            if (r != null) {
7389                r.taskDescription = td;
7390                r.task.updateTaskDescription();
7391            }
7392        }
7393    }
7394
7395    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7396        if (!pr.killedByAm) {
7397            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7398            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7399                    pr.processName, pr.setAdj, reason);
7400            pr.killedByAm = true;
7401            Process.killProcessQuiet(pr.pid);
7402        }
7403    }
7404
7405    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7406        tr.disposeThumbnail();
7407        mRecentTasks.remove(tr);
7408        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7409        Intent baseIntent = new Intent(
7410                tr.intent != null ? tr.intent : tr.affinityIntent);
7411        ComponentName component = baseIntent.getComponent();
7412        if (component == null) {
7413            Slog.w(TAG, "Now component for base intent of task: " + tr);
7414            return;
7415        }
7416
7417        // Find any running services associated with this app.
7418        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7419
7420        if (killProcesses) {
7421            // Find any running processes associated with this app.
7422            final String pkg = component.getPackageName();
7423            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7424            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7425            for (int i=0; i<pmap.size(); i++) {
7426                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7427                for (int j=0; j<uids.size(); j++) {
7428                    ProcessRecord proc = uids.valueAt(j);
7429                    if (proc.userId != tr.userId) {
7430                        continue;
7431                    }
7432                    if (!proc.pkgList.containsKey(pkg)) {
7433                        continue;
7434                    }
7435                    procs.add(proc);
7436                }
7437            }
7438
7439            // Kill the running processes.
7440            for (int i=0; i<procs.size(); i++) {
7441                ProcessRecord pr = procs.get(i);
7442                if (pr == mHomeProcess) {
7443                    // Don't kill the home process along with tasks from the same package.
7444                    continue;
7445                }
7446                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7447                    killUnneededProcessLocked(pr, "remove task");
7448                } else {
7449                    pr.waitingToKill = "remove task";
7450                }
7451            }
7452        }
7453    }
7454
7455    /**
7456     * Removes the task with the specified task id.
7457     *
7458     * @param taskId Identifier of the task to be removed.
7459     * @param flags Additional operational flags.  May be 0 or
7460     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7461     * @return Returns true if the given task was found and removed.
7462     */
7463    private boolean removeTaskByIdLocked(int taskId, int flags) {
7464        TaskRecord tr = recentTaskForIdLocked(taskId);
7465        if (tr != null) {
7466            tr.removeTaskActivitiesLocked();
7467            cleanUpRemovedTaskLocked(tr, flags);
7468            if (tr.isPersistable) {
7469                notifyTaskPersisterLocked(tr, true);
7470            }
7471            return true;
7472        }
7473        return false;
7474    }
7475
7476    @Override
7477    public boolean removeTask(int taskId, int flags) {
7478        synchronized (this) {
7479            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7480                    "removeTask()");
7481            long ident = Binder.clearCallingIdentity();
7482            try {
7483                return removeTaskByIdLocked(taskId, flags);
7484            } finally {
7485                Binder.restoreCallingIdentity(ident);
7486            }
7487        }
7488    }
7489
7490    /**
7491     * TODO: Add mController hook
7492     */
7493    @Override
7494    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7495        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7496                "moveTaskToFront()");
7497
7498        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7499        synchronized(this) {
7500            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7501                    Binder.getCallingUid(), "Task to front")) {
7502                ActivityOptions.abort(options);
7503                return;
7504            }
7505            final long origId = Binder.clearCallingIdentity();
7506            try {
7507                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7508                if (task == null) {
7509                    return;
7510                }
7511                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7512                    mStackSupervisor.showLockTaskToast();
7513                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7514                    return;
7515                }
7516                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7517                if (prev != null && prev.isRecentsActivity()) {
7518                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7519                }
7520                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7521            } finally {
7522                Binder.restoreCallingIdentity(origId);
7523            }
7524            ActivityOptions.abort(options);
7525        }
7526    }
7527
7528    @Override
7529    public void moveTaskToBack(int taskId) {
7530        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7531                "moveTaskToBack()");
7532
7533        synchronized(this) {
7534            TaskRecord tr = recentTaskForIdLocked(taskId);
7535            if (tr != null) {
7536                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7537                ActivityStack stack = tr.stack;
7538                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7539                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7540                            Binder.getCallingUid(), "Task to back")) {
7541                        return;
7542                    }
7543                }
7544                final long origId = Binder.clearCallingIdentity();
7545                try {
7546                    stack.moveTaskToBackLocked(taskId, null);
7547                } finally {
7548                    Binder.restoreCallingIdentity(origId);
7549                }
7550            }
7551        }
7552    }
7553
7554    /**
7555     * Moves an activity, and all of the other activities within the same task, to the bottom
7556     * of the history stack.  The activity's order within the task is unchanged.
7557     *
7558     * @param token A reference to the activity we wish to move
7559     * @param nonRoot If false then this only works if the activity is the root
7560     *                of a task; if true it will work for any activity in a task.
7561     * @return Returns true if the move completed, false if not.
7562     */
7563    @Override
7564    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7565        enforceNotIsolatedCaller("moveActivityTaskToBack");
7566        synchronized(this) {
7567            final long origId = Binder.clearCallingIdentity();
7568            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7569            if (taskId >= 0) {
7570                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7571            }
7572            Binder.restoreCallingIdentity(origId);
7573        }
7574        return false;
7575    }
7576
7577    @Override
7578    public void moveTaskBackwards(int task) {
7579        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7580                "moveTaskBackwards()");
7581
7582        synchronized(this) {
7583            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7584                    Binder.getCallingUid(), "Task backwards")) {
7585                return;
7586            }
7587            final long origId = Binder.clearCallingIdentity();
7588            moveTaskBackwardsLocked(task);
7589            Binder.restoreCallingIdentity(origId);
7590        }
7591    }
7592
7593    private final void moveTaskBackwardsLocked(int task) {
7594        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7595    }
7596
7597    @Override
7598    public IBinder getHomeActivityToken() throws RemoteException {
7599        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7600                "getHomeActivityToken()");
7601        synchronized (this) {
7602            return mStackSupervisor.getHomeActivityToken();
7603        }
7604    }
7605
7606    @Override
7607    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7608            IActivityContainerCallback callback) throws RemoteException {
7609        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7610                "createActivityContainer()");
7611        synchronized (this) {
7612            if (parentActivityToken == null) {
7613                throw new IllegalArgumentException("parent token must not be null");
7614            }
7615            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7616            if (r == null) {
7617                return null;
7618            }
7619            if (callback == null) {
7620                throw new IllegalArgumentException("callback must not be null");
7621            }
7622            return mStackSupervisor.createActivityContainer(r, callback);
7623        }
7624    }
7625
7626    @Override
7627    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7628        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7629                "deleteActivityContainer()");
7630        synchronized (this) {
7631            mStackSupervisor.deleteActivityContainer(container);
7632        }
7633    }
7634
7635    @Override
7636    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7637            throws RemoteException {
7638        synchronized (this) {
7639            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7640            if (stack != null) {
7641                return stack.mActivityContainer;
7642            }
7643            return null;
7644        }
7645    }
7646
7647    @Override
7648    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7649        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7650                "moveTaskToStack()");
7651        if (stackId == HOME_STACK_ID) {
7652            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7653                    new RuntimeException("here").fillInStackTrace());
7654        }
7655        synchronized (this) {
7656            long ident = Binder.clearCallingIdentity();
7657            try {
7658                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7659                        + stackId + " toTop=" + toTop);
7660                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7661            } finally {
7662                Binder.restoreCallingIdentity(ident);
7663            }
7664        }
7665    }
7666
7667    @Override
7668    public void resizeStack(int stackBoxId, Rect bounds) {
7669        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7670                "resizeStackBox()");
7671        long ident = Binder.clearCallingIdentity();
7672        try {
7673            mWindowManager.resizeStack(stackBoxId, bounds);
7674        } finally {
7675            Binder.restoreCallingIdentity(ident);
7676        }
7677    }
7678
7679    @Override
7680    public List<StackInfo> getAllStackInfos() {
7681        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7682                "getAllStackInfos()");
7683        long ident = Binder.clearCallingIdentity();
7684        try {
7685            synchronized (this) {
7686                return mStackSupervisor.getAllStackInfosLocked();
7687            }
7688        } finally {
7689            Binder.restoreCallingIdentity(ident);
7690        }
7691    }
7692
7693    @Override
7694    public StackInfo getStackInfo(int stackId) {
7695        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7696                "getStackInfo()");
7697        long ident = Binder.clearCallingIdentity();
7698        try {
7699            synchronized (this) {
7700                return mStackSupervisor.getStackInfoLocked(stackId);
7701            }
7702        } finally {
7703            Binder.restoreCallingIdentity(ident);
7704        }
7705    }
7706
7707    @Override
7708    public boolean isInHomeStack(int taskId) {
7709        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7710                "getStackInfo()");
7711        long ident = Binder.clearCallingIdentity();
7712        try {
7713            synchronized (this) {
7714                TaskRecord tr = recentTaskForIdLocked(taskId);
7715                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7716            }
7717        } finally {
7718            Binder.restoreCallingIdentity(ident);
7719        }
7720    }
7721
7722    @Override
7723    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7724        synchronized(this) {
7725            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7726        }
7727    }
7728
7729    private boolean isLockTaskAuthorized(String pkg) {
7730        final DevicePolicyManager dpm = (DevicePolicyManager)
7731                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7732        try {
7733            int uid = mContext.getPackageManager().getPackageUid(pkg,
7734                    Binder.getCallingUserHandle().getIdentifier());
7735            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7736        } catch (NameNotFoundException e) {
7737            return false;
7738        }
7739    }
7740
7741    void startLockTaskMode(TaskRecord task) {
7742        final String pkg;
7743        synchronized (this) {
7744            pkg = task.intent.getComponent().getPackageName();
7745        }
7746        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7747        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7748            final TaskRecord taskRecord = task;
7749            mHandler.post(new Runnable() {
7750                @Override
7751                public void run() {
7752                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7753                }
7754            });
7755            return;
7756        }
7757        long ident = Binder.clearCallingIdentity();
7758        try {
7759            synchronized (this) {
7760                // Since we lost lock on task, make sure it is still there.
7761                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7762                if (task != null) {
7763                    if (!isSystemInitiated
7764                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7765                        throw new IllegalArgumentException("Invalid task, not in foreground");
7766                    }
7767                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7768                }
7769            }
7770        } finally {
7771            Binder.restoreCallingIdentity(ident);
7772        }
7773    }
7774
7775    @Override
7776    public void startLockTaskMode(int taskId) {
7777        final TaskRecord task;
7778        long ident = Binder.clearCallingIdentity();
7779        try {
7780            synchronized (this) {
7781                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7782            }
7783        } finally {
7784            Binder.restoreCallingIdentity(ident);
7785        }
7786        if (task != null) {
7787            startLockTaskMode(task);
7788        }
7789    }
7790
7791    @Override
7792    public void startLockTaskMode(IBinder token) {
7793        final TaskRecord task;
7794        long ident = Binder.clearCallingIdentity();
7795        try {
7796            synchronized (this) {
7797                final ActivityRecord r = ActivityRecord.forToken(token);
7798                if (r == null) {
7799                    return;
7800                }
7801                task = r.task;
7802            }
7803        } finally {
7804            Binder.restoreCallingIdentity(ident);
7805        }
7806        if (task != null) {
7807            startLockTaskMode(task);
7808        }
7809    }
7810
7811    @Override
7812    public void startLockTaskModeOnCurrent() throws RemoteException {
7813        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7814        ActivityRecord r = null;
7815        synchronized (this) {
7816            r = mStackSupervisor.topRunningActivityLocked();
7817        }
7818        startLockTaskMode(r.task);
7819    }
7820
7821    @Override
7822    public void stopLockTaskMode() {
7823        // Verify that the user matches the package of the intent for the TaskRecord
7824        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7825        // and stopLockTaskMode.
7826        final int callingUid = Binder.getCallingUid();
7827        if (callingUid != Process.SYSTEM_UID) {
7828            try {
7829                String pkg =
7830                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7831                int uid = mContext.getPackageManager().getPackageUid(pkg,
7832                        Binder.getCallingUserHandle().getIdentifier());
7833                if (uid != callingUid) {
7834                    throw new SecurityException("Invalid uid, expected " + uid);
7835                }
7836            } catch (NameNotFoundException e) {
7837                Log.d(TAG, "stopLockTaskMode " + e);
7838                return;
7839            }
7840        }
7841        long ident = Binder.clearCallingIdentity();
7842        try {
7843            Log.d(TAG, "stopLockTaskMode");
7844            // Stop lock task
7845            synchronized (this) {
7846                mStackSupervisor.setLockTaskModeLocked(null, false);
7847            }
7848        } finally {
7849            Binder.restoreCallingIdentity(ident);
7850        }
7851    }
7852
7853    @Override
7854    public void stopLockTaskModeOnCurrent() throws RemoteException {
7855        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7856        long ident = Binder.clearCallingIdentity();
7857        try {
7858            stopLockTaskMode();
7859        } finally {
7860            Binder.restoreCallingIdentity(ident);
7861        }
7862    }
7863
7864    @Override
7865    public boolean isInLockTaskMode() {
7866        synchronized (this) {
7867            return mStackSupervisor.isInLockTaskMode();
7868        }
7869    }
7870
7871    // =========================================================
7872    // CONTENT PROVIDERS
7873    // =========================================================
7874
7875    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7876        List<ProviderInfo> providers = null;
7877        try {
7878            providers = AppGlobals.getPackageManager().
7879                queryContentProviders(app.processName, app.uid,
7880                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7881        } catch (RemoteException ex) {
7882        }
7883        if (DEBUG_MU)
7884            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7885        int userId = app.userId;
7886        if (providers != null) {
7887            int N = providers.size();
7888            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7889            for (int i=0; i<N; i++) {
7890                ProviderInfo cpi =
7891                    (ProviderInfo)providers.get(i);
7892                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7893                        cpi.name, cpi.flags);
7894                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7895                    // This is a singleton provider, but a user besides the
7896                    // default user is asking to initialize a process it runs
7897                    // in...  well, no, it doesn't actually run in this process,
7898                    // it runs in the process of the default user.  Get rid of it.
7899                    providers.remove(i);
7900                    N--;
7901                    i--;
7902                    continue;
7903                }
7904
7905                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7906                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7907                if (cpr == null) {
7908                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7909                    mProviderMap.putProviderByClass(comp, cpr);
7910                }
7911                if (DEBUG_MU)
7912                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7913                app.pubProviders.put(cpi.name, cpr);
7914                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7915                    // Don't add this if it is a platform component that is marked
7916                    // to run in multiple processes, because this is actually
7917                    // part of the framework so doesn't make sense to track as a
7918                    // separate apk in the process.
7919                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7920                            mProcessStats);
7921                }
7922                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7923            }
7924        }
7925        return providers;
7926    }
7927
7928    /**
7929     * Check if {@link ProcessRecord} has a possible chance at accessing the
7930     * given {@link ProviderInfo}. Final permission checking is always done
7931     * in {@link ContentProvider}.
7932     */
7933    private final String checkContentProviderPermissionLocked(
7934            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7935        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7936        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7937        boolean checkedGrants = false;
7938        if (checkUser) {
7939            // Looking for cross-user grants before enforcing the typical cross-users permissions
7940            if (UserHandle.getUserId(callingUid) != userId) {
7941                if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7942                    return null;
7943                }
7944                checkedGrants = true;
7945            }
7946            userId = handleIncomingUser(callingPid, callingUid, userId,
7947                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7948        }
7949        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7950                cpi.applicationInfo.uid, cpi.exported)
7951                == PackageManager.PERMISSION_GRANTED) {
7952            return null;
7953        }
7954        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7955                cpi.applicationInfo.uid, cpi.exported)
7956                == PackageManager.PERMISSION_GRANTED) {
7957            return null;
7958        }
7959
7960        PathPermission[] pps = cpi.pathPermissions;
7961        if (pps != null) {
7962            int i = pps.length;
7963            while (i > 0) {
7964                i--;
7965                PathPermission pp = pps[i];
7966                String pprperm = pp.getReadPermission();
7967                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
7968                        cpi.applicationInfo.uid, cpi.exported)
7969                        == PackageManager.PERMISSION_GRANTED) {
7970                    return null;
7971                }
7972                String ppwperm = pp.getWritePermission();
7973                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
7974                        cpi.applicationInfo.uid, cpi.exported)
7975                        == PackageManager.PERMISSION_GRANTED) {
7976                    return null;
7977                }
7978            }
7979        }
7980        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7981            return null;
7982        }
7983
7984        String msg;
7985        if (!cpi.exported) {
7986            msg = "Permission Denial: opening provider " + cpi.name
7987                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7988                    + ", uid=" + callingUid + ") that is not exported from uid "
7989                    + cpi.applicationInfo.uid;
7990        } else {
7991            msg = "Permission Denial: opening provider " + cpi.name
7992                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7993                    + ", uid=" + callingUid + ") requires "
7994                    + cpi.readPermission + " or " + cpi.writePermission;
7995        }
7996        Slog.w(TAG, msg);
7997        return msg;
7998    }
7999
8000    /**
8001     * Returns if the ContentProvider has granted a uri to callingUid
8002     */
8003    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8004        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8005        if (perms != null) {
8006            for (GrantUri grantUri : perms.keySet()) {
8007                if (grantUri.sourceUserId == userId || !checkUser) {
8008                    if (matchesProvider(grantUri.uri, cpi)) {
8009                        return true;
8010                    }
8011                }
8012            }
8013        }
8014        return false;
8015    }
8016
8017    /**
8018     * Returns true if the uri authority is one of the authorities specified in the provider.
8019     */
8020    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8021        String uriAuth = uri.getAuthority();
8022        String cpiAuth = cpi.authority;
8023        if (cpiAuth.indexOf(';') == -1) {
8024            return cpiAuth.equals(uriAuth);
8025        }
8026        String[] cpiAuths = cpiAuth.split(";");
8027        int length = cpiAuths.length;
8028        for (int i = 0; i < length; i++) {
8029            if (cpiAuths[i].equals(uriAuth)) return true;
8030        }
8031        return false;
8032    }
8033
8034    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8035            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8036        if (r != null) {
8037            for (int i=0; i<r.conProviders.size(); i++) {
8038                ContentProviderConnection conn = r.conProviders.get(i);
8039                if (conn.provider == cpr) {
8040                    if (DEBUG_PROVIDER) Slog.v(TAG,
8041                            "Adding provider requested by "
8042                            + r.processName + " from process "
8043                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8044                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8045                    if (stable) {
8046                        conn.stableCount++;
8047                        conn.numStableIncs++;
8048                    } else {
8049                        conn.unstableCount++;
8050                        conn.numUnstableIncs++;
8051                    }
8052                    return conn;
8053                }
8054            }
8055            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8056            if (stable) {
8057                conn.stableCount = 1;
8058                conn.numStableIncs = 1;
8059            } else {
8060                conn.unstableCount = 1;
8061                conn.numUnstableIncs = 1;
8062            }
8063            cpr.connections.add(conn);
8064            r.conProviders.add(conn);
8065            return conn;
8066        }
8067        cpr.addExternalProcessHandleLocked(externalProcessToken);
8068        return null;
8069    }
8070
8071    boolean decProviderCountLocked(ContentProviderConnection conn,
8072            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8073        if (conn != null) {
8074            cpr = conn.provider;
8075            if (DEBUG_PROVIDER) Slog.v(TAG,
8076                    "Removing provider requested by "
8077                    + conn.client.processName + " from process "
8078                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8079                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8080            if (stable) {
8081                conn.stableCount--;
8082            } else {
8083                conn.unstableCount--;
8084            }
8085            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8086                cpr.connections.remove(conn);
8087                conn.client.conProviders.remove(conn);
8088                return true;
8089            }
8090            return false;
8091        }
8092        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8093        return false;
8094    }
8095
8096    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8097            String name, IBinder token, boolean stable, int userId) {
8098        ContentProviderRecord cpr;
8099        ContentProviderConnection conn = null;
8100        ProviderInfo cpi = null;
8101
8102        synchronized(this) {
8103            ProcessRecord r = null;
8104            if (caller != null) {
8105                r = getRecordForAppLocked(caller);
8106                if (r == null) {
8107                    throw new SecurityException(
8108                            "Unable to find app for caller " + caller
8109                          + " (pid=" + Binder.getCallingPid()
8110                          + ") when getting content provider " + name);
8111                }
8112            }
8113
8114            boolean checkCrossUser = true;
8115
8116            // First check if this content provider has been published...
8117            cpr = mProviderMap.getProviderByName(name, userId);
8118            // If that didn't work, check if it exists for user 0 and then
8119            // verify that it's a singleton provider before using it.
8120            if (cpr == null && userId != UserHandle.USER_OWNER) {
8121                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8122                if (cpr != null) {
8123                    cpi = cpr.info;
8124                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8125                            cpi.name, cpi.flags)
8126                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8127                        userId = UserHandle.USER_OWNER;
8128                        checkCrossUser = false;
8129                    } else {
8130                        cpr = null;
8131                        cpi = null;
8132                    }
8133                }
8134            }
8135
8136            boolean providerRunning = cpr != null;
8137            if (providerRunning) {
8138                cpi = cpr.info;
8139                String msg;
8140                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8141                        != null) {
8142                    throw new SecurityException(msg);
8143                }
8144
8145                if (r != null && cpr.canRunHere(r)) {
8146                    // This provider has been published or is in the process
8147                    // of being published...  but it is also allowed to run
8148                    // in the caller's process, so don't make a connection
8149                    // and just let the caller instantiate its own instance.
8150                    ContentProviderHolder holder = cpr.newHolder(null);
8151                    // don't give caller the provider object, it needs
8152                    // to make its own.
8153                    holder.provider = null;
8154                    return holder;
8155                }
8156
8157                final long origId = Binder.clearCallingIdentity();
8158
8159                // In this case the provider instance already exists, so we can
8160                // return it right away.
8161                conn = incProviderCountLocked(r, cpr, token, stable);
8162                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8163                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8164                        // If this is a perceptible app accessing the provider,
8165                        // make sure to count it as being accessed and thus
8166                        // back up on the LRU list.  This is good because
8167                        // content providers are often expensive to start.
8168                        updateLruProcessLocked(cpr.proc, false, null);
8169                    }
8170                }
8171
8172                if (cpr.proc != null) {
8173                    if (false) {
8174                        if (cpr.name.flattenToShortString().equals(
8175                                "com.android.providers.calendar/.CalendarProvider2")) {
8176                            Slog.v(TAG, "****************** KILLING "
8177                                + cpr.name.flattenToShortString());
8178                            Process.killProcess(cpr.proc.pid);
8179                        }
8180                    }
8181                    boolean success = updateOomAdjLocked(cpr.proc);
8182                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8183                    // NOTE: there is still a race here where a signal could be
8184                    // pending on the process even though we managed to update its
8185                    // adj level.  Not sure what to do about this, but at least
8186                    // the race is now smaller.
8187                    if (!success) {
8188                        // Uh oh...  it looks like the provider's process
8189                        // has been killed on us.  We need to wait for a new
8190                        // process to be started, and make sure its death
8191                        // doesn't kill our process.
8192                        Slog.i(TAG,
8193                                "Existing provider " + cpr.name.flattenToShortString()
8194                                + " is crashing; detaching " + r);
8195                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8196                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8197                        if (!lastRef) {
8198                            // This wasn't the last ref our process had on
8199                            // the provider...  we have now been killed, bail.
8200                            return null;
8201                        }
8202                        providerRunning = false;
8203                        conn = null;
8204                    }
8205                }
8206
8207                Binder.restoreCallingIdentity(origId);
8208            }
8209
8210            boolean singleton;
8211            if (!providerRunning) {
8212                try {
8213                    cpi = AppGlobals.getPackageManager().
8214                        resolveContentProvider(name,
8215                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8216                } catch (RemoteException ex) {
8217                }
8218                if (cpi == null) {
8219                    return null;
8220                }
8221                // If the provider is a singleton AND
8222                // (it's a call within the same user || the provider is a
8223                // privileged app)
8224                // Then allow connecting to the singleton provider
8225                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8226                        cpi.name, cpi.flags)
8227                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8228                if (singleton) {
8229                    userId = UserHandle.USER_OWNER;
8230                }
8231                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8232
8233                String msg;
8234                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8235                        != null) {
8236                    throw new SecurityException(msg);
8237                }
8238
8239                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8240                        && !cpi.processName.equals("system")) {
8241                    // If this content provider does not run in the system
8242                    // process, and the system is not yet ready to run other
8243                    // processes, then fail fast instead of hanging.
8244                    throw new IllegalArgumentException(
8245                            "Attempt to launch content provider before system ready");
8246                }
8247
8248                // Make sure that the user who owns this provider is started.  If not,
8249                // we don't want to allow it to run.
8250                if (mStartedUsers.get(userId) == null) {
8251                    Slog.w(TAG, "Unable to launch app "
8252                            + cpi.applicationInfo.packageName + "/"
8253                            + cpi.applicationInfo.uid + " for provider "
8254                            + name + ": user " + userId + " is stopped");
8255                    return null;
8256                }
8257
8258                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8259                cpr = mProviderMap.getProviderByClass(comp, userId);
8260                final boolean firstClass = cpr == null;
8261                if (firstClass) {
8262                    try {
8263                        ApplicationInfo ai =
8264                            AppGlobals.getPackageManager().
8265                                getApplicationInfo(
8266                                        cpi.applicationInfo.packageName,
8267                                        STOCK_PM_FLAGS, userId);
8268                        if (ai == null) {
8269                            Slog.w(TAG, "No package info for content provider "
8270                                    + cpi.name);
8271                            return null;
8272                        }
8273                        ai = getAppInfoForUser(ai, userId);
8274                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8275                    } catch (RemoteException ex) {
8276                        // pm is in same process, this will never happen.
8277                    }
8278                }
8279
8280                if (r != null && cpr.canRunHere(r)) {
8281                    // If this is a multiprocess provider, then just return its
8282                    // info and allow the caller to instantiate it.  Only do
8283                    // this if the provider is the same user as the caller's
8284                    // process, or can run as root (so can be in any process).
8285                    return cpr.newHolder(null);
8286                }
8287
8288                if (DEBUG_PROVIDER) {
8289                    RuntimeException e = new RuntimeException("here");
8290                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8291                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8292                }
8293
8294                // This is single process, and our app is now connecting to it.
8295                // See if we are already in the process of launching this
8296                // provider.
8297                final int N = mLaunchingProviders.size();
8298                int i;
8299                for (i=0; i<N; i++) {
8300                    if (mLaunchingProviders.get(i) == cpr) {
8301                        break;
8302                    }
8303                }
8304
8305                // If the provider is not already being launched, then get it
8306                // started.
8307                if (i >= N) {
8308                    final long origId = Binder.clearCallingIdentity();
8309
8310                    try {
8311                        // Content provider is now in use, its package can't be stopped.
8312                        try {
8313                            AppGlobals.getPackageManager().setPackageStoppedState(
8314                                    cpr.appInfo.packageName, false, userId);
8315                        } catch (RemoteException e) {
8316                        } catch (IllegalArgumentException e) {
8317                            Slog.w(TAG, "Failed trying to unstop package "
8318                                    + cpr.appInfo.packageName + ": " + e);
8319                        }
8320
8321                        // Use existing process if already started
8322                        ProcessRecord proc = getProcessRecordLocked(
8323                                cpi.processName, cpr.appInfo.uid, false);
8324                        if (proc != null && proc.thread != null) {
8325                            if (DEBUG_PROVIDER) {
8326                                Slog.d(TAG, "Installing in existing process " + proc);
8327                            }
8328                            proc.pubProviders.put(cpi.name, cpr);
8329                            try {
8330                                proc.thread.scheduleInstallProvider(cpi);
8331                            } catch (RemoteException e) {
8332                            }
8333                        } else {
8334                            proc = startProcessLocked(cpi.processName,
8335                                    cpr.appInfo, false, 0, "content provider",
8336                                    new ComponentName(cpi.applicationInfo.packageName,
8337                                            cpi.name), false, false, false);
8338                            if (proc == null) {
8339                                Slog.w(TAG, "Unable to launch app "
8340                                        + cpi.applicationInfo.packageName + "/"
8341                                        + cpi.applicationInfo.uid + " for provider "
8342                                        + name + ": process is bad");
8343                                return null;
8344                            }
8345                        }
8346                        cpr.launchingApp = proc;
8347                        mLaunchingProviders.add(cpr);
8348                    } finally {
8349                        Binder.restoreCallingIdentity(origId);
8350                    }
8351                }
8352
8353                // Make sure the provider is published (the same provider class
8354                // may be published under multiple names).
8355                if (firstClass) {
8356                    mProviderMap.putProviderByClass(comp, cpr);
8357                }
8358
8359                mProviderMap.putProviderByName(name, cpr);
8360                conn = incProviderCountLocked(r, cpr, token, stable);
8361                if (conn != null) {
8362                    conn.waiting = true;
8363                }
8364            }
8365        }
8366
8367        // Wait for the provider to be published...
8368        synchronized (cpr) {
8369            while (cpr.provider == null) {
8370                if (cpr.launchingApp == null) {
8371                    Slog.w(TAG, "Unable to launch app "
8372                            + cpi.applicationInfo.packageName + "/"
8373                            + cpi.applicationInfo.uid + " for provider "
8374                            + name + ": launching app became null");
8375                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8376                            UserHandle.getUserId(cpi.applicationInfo.uid),
8377                            cpi.applicationInfo.packageName,
8378                            cpi.applicationInfo.uid, name);
8379                    return null;
8380                }
8381                try {
8382                    if (DEBUG_MU) {
8383                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8384                                + cpr.launchingApp);
8385                    }
8386                    if (conn != null) {
8387                        conn.waiting = true;
8388                    }
8389                    cpr.wait();
8390                } catch (InterruptedException ex) {
8391                } finally {
8392                    if (conn != null) {
8393                        conn.waiting = false;
8394                    }
8395                }
8396            }
8397        }
8398        return cpr != null ? cpr.newHolder(conn) : null;
8399    }
8400
8401    @Override
8402    public final ContentProviderHolder getContentProvider(
8403            IApplicationThread caller, String name, int userId, boolean stable) {
8404        enforceNotIsolatedCaller("getContentProvider");
8405        if (caller == null) {
8406            String msg = "null IApplicationThread when getting content provider "
8407                    + name;
8408            Slog.w(TAG, msg);
8409            throw new SecurityException(msg);
8410        }
8411        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8412        // with cross-user grant.
8413        return getContentProviderImpl(caller, name, null, stable, userId);
8414    }
8415
8416    public ContentProviderHolder getContentProviderExternal(
8417            String name, int userId, IBinder token) {
8418        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8419            "Do not have permission in call getContentProviderExternal()");
8420        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8421                false, true, "getContentProvider", null);
8422        return getContentProviderExternalUnchecked(name, token, userId);
8423    }
8424
8425    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8426            IBinder token, int userId) {
8427        return getContentProviderImpl(null, name, token, true, userId);
8428    }
8429
8430    /**
8431     * Drop a content provider from a ProcessRecord's bookkeeping
8432     */
8433    public void removeContentProvider(IBinder connection, boolean stable) {
8434        enforceNotIsolatedCaller("removeContentProvider");
8435        long ident = Binder.clearCallingIdentity();
8436        try {
8437            synchronized (this) {
8438                ContentProviderConnection conn;
8439                try {
8440                    conn = (ContentProviderConnection)connection;
8441                } catch (ClassCastException e) {
8442                    String msg ="removeContentProvider: " + connection
8443                            + " not a ContentProviderConnection";
8444                    Slog.w(TAG, msg);
8445                    throw new IllegalArgumentException(msg);
8446                }
8447                if (conn == null) {
8448                    throw new NullPointerException("connection is null");
8449                }
8450                if (decProviderCountLocked(conn, null, null, stable)) {
8451                    updateOomAdjLocked();
8452                }
8453            }
8454        } finally {
8455            Binder.restoreCallingIdentity(ident);
8456        }
8457    }
8458
8459    public void removeContentProviderExternal(String name, IBinder token) {
8460        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8461            "Do not have permission in call removeContentProviderExternal()");
8462        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8463    }
8464
8465    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8466        synchronized (this) {
8467            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8468            if(cpr == null) {
8469                //remove from mProvidersByClass
8470                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8471                return;
8472            }
8473
8474            //update content provider record entry info
8475            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8476            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8477            if (localCpr.hasExternalProcessHandles()) {
8478                if (localCpr.removeExternalProcessHandleLocked(token)) {
8479                    updateOomAdjLocked();
8480                } else {
8481                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8482                            + " with no external reference for token: "
8483                            + token + ".");
8484                }
8485            } else {
8486                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8487                        + " with no external references.");
8488            }
8489        }
8490    }
8491
8492    public final void publishContentProviders(IApplicationThread caller,
8493            List<ContentProviderHolder> providers) {
8494        if (providers == null) {
8495            return;
8496        }
8497
8498        enforceNotIsolatedCaller("publishContentProviders");
8499        synchronized (this) {
8500            final ProcessRecord r = getRecordForAppLocked(caller);
8501            if (DEBUG_MU)
8502                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8503            if (r == null) {
8504                throw new SecurityException(
8505                        "Unable to find app for caller " + caller
8506                      + " (pid=" + Binder.getCallingPid()
8507                      + ") when publishing content providers");
8508            }
8509
8510            final long origId = Binder.clearCallingIdentity();
8511
8512            final int N = providers.size();
8513            for (int i=0; i<N; i++) {
8514                ContentProviderHolder src = providers.get(i);
8515                if (src == null || src.info == null || src.provider == null) {
8516                    continue;
8517                }
8518                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8519                if (DEBUG_MU)
8520                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8521                if (dst != null) {
8522                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8523                    mProviderMap.putProviderByClass(comp, dst);
8524                    String names[] = dst.info.authority.split(";");
8525                    for (int j = 0; j < names.length; j++) {
8526                        mProviderMap.putProviderByName(names[j], dst);
8527                    }
8528
8529                    int NL = mLaunchingProviders.size();
8530                    int j;
8531                    for (j=0; j<NL; j++) {
8532                        if (mLaunchingProviders.get(j) == dst) {
8533                            mLaunchingProviders.remove(j);
8534                            j--;
8535                            NL--;
8536                        }
8537                    }
8538                    synchronized (dst) {
8539                        dst.provider = src.provider;
8540                        dst.proc = r;
8541                        dst.notifyAll();
8542                    }
8543                    updateOomAdjLocked(r);
8544                }
8545            }
8546
8547            Binder.restoreCallingIdentity(origId);
8548        }
8549    }
8550
8551    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8552        ContentProviderConnection conn;
8553        try {
8554            conn = (ContentProviderConnection)connection;
8555        } catch (ClassCastException e) {
8556            String msg ="refContentProvider: " + connection
8557                    + " not a ContentProviderConnection";
8558            Slog.w(TAG, msg);
8559            throw new IllegalArgumentException(msg);
8560        }
8561        if (conn == null) {
8562            throw new NullPointerException("connection is null");
8563        }
8564
8565        synchronized (this) {
8566            if (stable > 0) {
8567                conn.numStableIncs += stable;
8568            }
8569            stable = conn.stableCount + stable;
8570            if (stable < 0) {
8571                throw new IllegalStateException("stableCount < 0: " + stable);
8572            }
8573
8574            if (unstable > 0) {
8575                conn.numUnstableIncs += unstable;
8576            }
8577            unstable = conn.unstableCount + unstable;
8578            if (unstable < 0) {
8579                throw new IllegalStateException("unstableCount < 0: " + unstable);
8580            }
8581
8582            if ((stable+unstable) <= 0) {
8583                throw new IllegalStateException("ref counts can't go to zero here: stable="
8584                        + stable + " unstable=" + unstable);
8585            }
8586            conn.stableCount = stable;
8587            conn.unstableCount = unstable;
8588            return !conn.dead;
8589        }
8590    }
8591
8592    public void unstableProviderDied(IBinder connection) {
8593        ContentProviderConnection conn;
8594        try {
8595            conn = (ContentProviderConnection)connection;
8596        } catch (ClassCastException e) {
8597            String msg ="refContentProvider: " + connection
8598                    + " not a ContentProviderConnection";
8599            Slog.w(TAG, msg);
8600            throw new IllegalArgumentException(msg);
8601        }
8602        if (conn == null) {
8603            throw new NullPointerException("connection is null");
8604        }
8605
8606        // Safely retrieve the content provider associated with the connection.
8607        IContentProvider provider;
8608        synchronized (this) {
8609            provider = conn.provider.provider;
8610        }
8611
8612        if (provider == null) {
8613            // Um, yeah, we're way ahead of you.
8614            return;
8615        }
8616
8617        // Make sure the caller is being honest with us.
8618        if (provider.asBinder().pingBinder()) {
8619            // Er, no, still looks good to us.
8620            synchronized (this) {
8621                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8622                        + " says " + conn + " died, but we don't agree");
8623                return;
8624            }
8625        }
8626
8627        // Well look at that!  It's dead!
8628        synchronized (this) {
8629            if (conn.provider.provider != provider) {
8630                // But something changed...  good enough.
8631                return;
8632            }
8633
8634            ProcessRecord proc = conn.provider.proc;
8635            if (proc == null || proc.thread == null) {
8636                // Seems like the process is already cleaned up.
8637                return;
8638            }
8639
8640            // As far as we're concerned, this is just like receiving a
8641            // death notification...  just a bit prematurely.
8642            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8643                    + ") early provider death");
8644            final long ident = Binder.clearCallingIdentity();
8645            try {
8646                appDiedLocked(proc, proc.pid, proc.thread);
8647            } finally {
8648                Binder.restoreCallingIdentity(ident);
8649            }
8650        }
8651    }
8652
8653    @Override
8654    public void appNotRespondingViaProvider(IBinder connection) {
8655        enforceCallingPermission(
8656                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8657
8658        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8659        if (conn == null) {
8660            Slog.w(TAG, "ContentProviderConnection is null");
8661            return;
8662        }
8663
8664        final ProcessRecord host = conn.provider.proc;
8665        if (host == null) {
8666            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8667            return;
8668        }
8669
8670        final long token = Binder.clearCallingIdentity();
8671        try {
8672            appNotResponding(host, null, null, false, "ContentProvider not responding");
8673        } finally {
8674            Binder.restoreCallingIdentity(token);
8675        }
8676    }
8677
8678    public final void installSystemProviders() {
8679        List<ProviderInfo> providers;
8680        synchronized (this) {
8681            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8682            providers = generateApplicationProvidersLocked(app);
8683            if (providers != null) {
8684                for (int i=providers.size()-1; i>=0; i--) {
8685                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8686                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8687                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8688                                + ": not system .apk");
8689                        providers.remove(i);
8690                    }
8691                }
8692            }
8693        }
8694        if (providers != null) {
8695            mSystemThread.installSystemProviders(providers);
8696        }
8697
8698        mCoreSettingsObserver = new CoreSettingsObserver(this);
8699
8700        mUsageStatsService.monitorPackages();
8701    }
8702
8703    /**
8704     * Allows app to retrieve the MIME type of a URI without having permission
8705     * to access its content provider.
8706     *
8707     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8708     *
8709     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8710     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8711     */
8712    public String getProviderMimeType(Uri uri, int userId) {
8713        enforceNotIsolatedCaller("getProviderMimeType");
8714        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8715                userId, false, true, "getProviderMimeType", null);
8716        final String name = uri.getAuthority();
8717        final long ident = Binder.clearCallingIdentity();
8718        ContentProviderHolder holder = null;
8719
8720        try {
8721            holder = getContentProviderExternalUnchecked(name, null, userId);
8722            if (holder != null) {
8723                return holder.provider.getType(uri);
8724            }
8725        } catch (RemoteException e) {
8726            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8727            return null;
8728        } finally {
8729            if (holder != null) {
8730                removeContentProviderExternalUnchecked(name, null, userId);
8731            }
8732            Binder.restoreCallingIdentity(ident);
8733        }
8734
8735        return null;
8736    }
8737
8738    // =========================================================
8739    // GLOBAL MANAGEMENT
8740    // =========================================================
8741
8742    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8743            boolean isolated) {
8744        String proc = customProcess != null ? customProcess : info.processName;
8745        BatteryStatsImpl.Uid.Proc ps = null;
8746        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8747        int uid = info.uid;
8748        if (isolated) {
8749            int userId = UserHandle.getUserId(uid);
8750            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8751            while (true) {
8752                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8753                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8754                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8755                }
8756                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8757                mNextIsolatedProcessUid++;
8758                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8759                    // No process for this uid, use it.
8760                    break;
8761                }
8762                stepsLeft--;
8763                if (stepsLeft <= 0) {
8764                    return null;
8765                }
8766            }
8767        }
8768        return new ProcessRecord(stats, info, proc, uid);
8769    }
8770
8771    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8772            String abiOverride) {
8773        ProcessRecord app;
8774        if (!isolated) {
8775            app = getProcessRecordLocked(info.processName, info.uid, true);
8776        } else {
8777            app = null;
8778        }
8779
8780        if (app == null) {
8781            app = newProcessRecordLocked(info, null, isolated);
8782            mProcessNames.put(info.processName, app.uid, app);
8783            if (isolated) {
8784                mIsolatedProcesses.put(app.uid, app);
8785            }
8786            updateLruProcessLocked(app, false, null);
8787            updateOomAdjLocked();
8788        }
8789
8790        // This package really, really can not be stopped.
8791        try {
8792            AppGlobals.getPackageManager().setPackageStoppedState(
8793                    info.packageName, false, UserHandle.getUserId(app.uid));
8794        } catch (RemoteException e) {
8795        } catch (IllegalArgumentException e) {
8796            Slog.w(TAG, "Failed trying to unstop package "
8797                    + info.packageName + ": " + e);
8798        }
8799
8800        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8801                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8802            app.persistent = true;
8803            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8804        }
8805        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8806            mPersistentStartingProcesses.add(app);
8807            startProcessLocked(app, "added application", app.processName,
8808                    abiOverride);
8809        }
8810
8811        return app;
8812    }
8813
8814    public void unhandledBack() {
8815        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8816                "unhandledBack()");
8817
8818        synchronized(this) {
8819            final long origId = Binder.clearCallingIdentity();
8820            try {
8821                getFocusedStack().unhandledBackLocked();
8822            } finally {
8823                Binder.restoreCallingIdentity(origId);
8824            }
8825        }
8826    }
8827
8828    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8829        enforceNotIsolatedCaller("openContentUri");
8830        final int userId = UserHandle.getCallingUserId();
8831        String name = uri.getAuthority();
8832        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8833        ParcelFileDescriptor pfd = null;
8834        if (cph != null) {
8835            // We record the binder invoker's uid in thread-local storage before
8836            // going to the content provider to open the file.  Later, in the code
8837            // that handles all permissions checks, we look for this uid and use
8838            // that rather than the Activity Manager's own uid.  The effect is that
8839            // we do the check against the caller's permissions even though it looks
8840            // to the content provider like the Activity Manager itself is making
8841            // the request.
8842            sCallerIdentity.set(new Identity(
8843                    Binder.getCallingPid(), Binder.getCallingUid()));
8844            try {
8845                pfd = cph.provider.openFile(null, uri, "r", null);
8846            } catch (FileNotFoundException e) {
8847                // do nothing; pfd will be returned null
8848            } finally {
8849                // Ensure that whatever happens, we clean up the identity state
8850                sCallerIdentity.remove();
8851            }
8852
8853            // We've got the fd now, so we're done with the provider.
8854            removeContentProviderExternalUnchecked(name, null, userId);
8855        } else {
8856            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8857        }
8858        return pfd;
8859    }
8860
8861    // Actually is sleeping or shutting down or whatever else in the future
8862    // is an inactive state.
8863    public boolean isSleepingOrShuttingDown() {
8864        return mSleeping || mShuttingDown;
8865    }
8866
8867    public boolean isSleeping() {
8868        return mSleeping;
8869    }
8870
8871    void goingToSleep() {
8872        synchronized(this) {
8873            mWentToSleep = true;
8874            updateEventDispatchingLocked();
8875            goToSleepIfNeededLocked();
8876        }
8877    }
8878
8879    void finishRunningVoiceLocked() {
8880        if (mRunningVoice) {
8881            mRunningVoice = false;
8882            goToSleepIfNeededLocked();
8883        }
8884    }
8885
8886    void goToSleepIfNeededLocked() {
8887        if (mWentToSleep && !mRunningVoice) {
8888            if (!mSleeping) {
8889                mSleeping = true;
8890                mStackSupervisor.goingToSleepLocked();
8891
8892                // Initialize the wake times of all processes.
8893                checkExcessivePowerUsageLocked(false);
8894                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8895                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8896                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8897            }
8898        }
8899    }
8900
8901    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8902        mTaskPersister.notify(task, flush);
8903    }
8904
8905    @Override
8906    public boolean shutdown(int timeout) {
8907        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8908                != PackageManager.PERMISSION_GRANTED) {
8909            throw new SecurityException("Requires permission "
8910                    + android.Manifest.permission.SHUTDOWN);
8911        }
8912
8913        boolean timedout = false;
8914
8915        synchronized(this) {
8916            mShuttingDown = true;
8917            updateEventDispatchingLocked();
8918            timedout = mStackSupervisor.shutdownLocked(timeout);
8919        }
8920
8921        mAppOpsService.shutdown();
8922        mUsageStatsService.shutdown();
8923        mBatteryStatsService.shutdown();
8924        synchronized (this) {
8925            mProcessStats.shutdownLocked();
8926        }
8927        notifyTaskPersisterLocked(null, true);
8928
8929        return timedout;
8930    }
8931
8932    public final void activitySlept(IBinder token) {
8933        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8934
8935        final long origId = Binder.clearCallingIdentity();
8936
8937        synchronized (this) {
8938            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8939            if (r != null) {
8940                mStackSupervisor.activitySleptLocked(r);
8941            }
8942        }
8943
8944        Binder.restoreCallingIdentity(origId);
8945    }
8946
8947    void logLockScreen(String msg) {
8948        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8949                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8950                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8951                mStackSupervisor.mDismissKeyguardOnNextActivity);
8952    }
8953
8954    private void comeOutOfSleepIfNeededLocked() {
8955        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8956            if (mSleeping) {
8957                mSleeping = false;
8958                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8959            }
8960        }
8961    }
8962
8963    void wakingUp() {
8964        synchronized(this) {
8965            mWentToSleep = false;
8966            updateEventDispatchingLocked();
8967            comeOutOfSleepIfNeededLocked();
8968        }
8969    }
8970
8971    void startRunningVoiceLocked() {
8972        if (!mRunningVoice) {
8973            mRunningVoice = true;
8974            comeOutOfSleepIfNeededLocked();
8975        }
8976    }
8977
8978    private void updateEventDispatchingLocked() {
8979        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8980    }
8981
8982    public void setLockScreenShown(boolean shown) {
8983        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8984                != PackageManager.PERMISSION_GRANTED) {
8985            throw new SecurityException("Requires permission "
8986                    + android.Manifest.permission.DEVICE_POWER);
8987        }
8988
8989        synchronized(this) {
8990            long ident = Binder.clearCallingIdentity();
8991            try {
8992                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8993                mLockScreenShown = shown;
8994                comeOutOfSleepIfNeededLocked();
8995            } finally {
8996                Binder.restoreCallingIdentity(ident);
8997            }
8998        }
8999    }
9000
9001    public void stopAppSwitches() {
9002        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9003                != PackageManager.PERMISSION_GRANTED) {
9004            throw new SecurityException("Requires permission "
9005                    + android.Manifest.permission.STOP_APP_SWITCHES);
9006        }
9007
9008        synchronized(this) {
9009            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9010                    + APP_SWITCH_DELAY_TIME;
9011            mDidAppSwitch = false;
9012            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9013            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9014            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9015        }
9016    }
9017
9018    public void resumeAppSwitches() {
9019        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9020                != PackageManager.PERMISSION_GRANTED) {
9021            throw new SecurityException("Requires permission "
9022                    + android.Manifest.permission.STOP_APP_SWITCHES);
9023        }
9024
9025        synchronized(this) {
9026            // Note that we don't execute any pending app switches... we will
9027            // let those wait until either the timeout, or the next start
9028            // activity request.
9029            mAppSwitchesAllowedTime = 0;
9030        }
9031    }
9032
9033    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9034            String name) {
9035        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9036            return true;
9037        }
9038
9039        final int perm = checkComponentPermission(
9040                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9041                callingUid, -1, true);
9042        if (perm == PackageManager.PERMISSION_GRANTED) {
9043            return true;
9044        }
9045
9046        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9047        return false;
9048    }
9049
9050    public void setDebugApp(String packageName, boolean waitForDebugger,
9051            boolean persistent) {
9052        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9053                "setDebugApp()");
9054
9055        long ident = Binder.clearCallingIdentity();
9056        try {
9057            // Note that this is not really thread safe if there are multiple
9058            // callers into it at the same time, but that's not a situation we
9059            // care about.
9060            if (persistent) {
9061                final ContentResolver resolver = mContext.getContentResolver();
9062                Settings.Global.putString(
9063                    resolver, Settings.Global.DEBUG_APP,
9064                    packageName);
9065                Settings.Global.putInt(
9066                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9067                    waitForDebugger ? 1 : 0);
9068            }
9069
9070            synchronized (this) {
9071                if (!persistent) {
9072                    mOrigDebugApp = mDebugApp;
9073                    mOrigWaitForDebugger = mWaitForDebugger;
9074                }
9075                mDebugApp = packageName;
9076                mWaitForDebugger = waitForDebugger;
9077                mDebugTransient = !persistent;
9078                if (packageName != null) {
9079                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9080                            false, UserHandle.USER_ALL, "set debug app");
9081                }
9082            }
9083        } finally {
9084            Binder.restoreCallingIdentity(ident);
9085        }
9086    }
9087
9088    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9089        synchronized (this) {
9090            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9091            if (!isDebuggable) {
9092                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9093                    throw new SecurityException("Process not debuggable: " + app.packageName);
9094                }
9095            }
9096
9097            mOpenGlTraceApp = processName;
9098        }
9099    }
9100
9101    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9102            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9103        synchronized (this) {
9104            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9105            if (!isDebuggable) {
9106                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9107                    throw new SecurityException("Process not debuggable: " + app.packageName);
9108                }
9109            }
9110            mProfileApp = processName;
9111            mProfileFile = profileFile;
9112            if (mProfileFd != null) {
9113                try {
9114                    mProfileFd.close();
9115                } catch (IOException e) {
9116                }
9117                mProfileFd = null;
9118            }
9119            mProfileFd = profileFd;
9120            mProfileType = 0;
9121            mAutoStopProfiler = autoStopProfiler;
9122        }
9123    }
9124
9125    @Override
9126    public void setAlwaysFinish(boolean enabled) {
9127        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9128                "setAlwaysFinish()");
9129
9130        Settings.Global.putInt(
9131                mContext.getContentResolver(),
9132                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9133
9134        synchronized (this) {
9135            mAlwaysFinishActivities = enabled;
9136        }
9137    }
9138
9139    @Override
9140    public void setActivityController(IActivityController controller) {
9141        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9142                "setActivityController()");
9143        synchronized (this) {
9144            mController = controller;
9145            Watchdog.getInstance().setActivityController(controller);
9146        }
9147    }
9148
9149    @Override
9150    public void setUserIsMonkey(boolean userIsMonkey) {
9151        synchronized (this) {
9152            synchronized (mPidsSelfLocked) {
9153                final int callingPid = Binder.getCallingPid();
9154                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9155                if (precessRecord == null) {
9156                    throw new SecurityException("Unknown process: " + callingPid);
9157                }
9158                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9159                    throw new SecurityException("Only an instrumentation process "
9160                            + "with a UiAutomation can call setUserIsMonkey");
9161                }
9162            }
9163            mUserIsMonkey = userIsMonkey;
9164        }
9165    }
9166
9167    @Override
9168    public boolean isUserAMonkey() {
9169        synchronized (this) {
9170            // If there is a controller also implies the user is a monkey.
9171            return (mUserIsMonkey || mController != null);
9172        }
9173    }
9174
9175    public void requestBugReport() {
9176        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9177        SystemProperties.set("ctl.start", "bugreport");
9178    }
9179
9180    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9181        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9182    }
9183
9184    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9185        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9186            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9187        }
9188        return KEY_DISPATCHING_TIMEOUT;
9189    }
9190
9191    @Override
9192    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9193        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9194                != PackageManager.PERMISSION_GRANTED) {
9195            throw new SecurityException("Requires permission "
9196                    + android.Manifest.permission.FILTER_EVENTS);
9197        }
9198        ProcessRecord proc;
9199        long timeout;
9200        synchronized (this) {
9201            synchronized (mPidsSelfLocked) {
9202                proc = mPidsSelfLocked.get(pid);
9203            }
9204            timeout = getInputDispatchingTimeoutLocked(proc);
9205        }
9206
9207        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9208            return -1;
9209        }
9210
9211        return timeout;
9212    }
9213
9214    /**
9215     * Handle input dispatching timeouts.
9216     * Returns whether input dispatching should be aborted or not.
9217     */
9218    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9219            final ActivityRecord activity, final ActivityRecord parent,
9220            final boolean aboveSystem, String reason) {
9221        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9222                != PackageManager.PERMISSION_GRANTED) {
9223            throw new SecurityException("Requires permission "
9224                    + android.Manifest.permission.FILTER_EVENTS);
9225        }
9226
9227        final String annotation;
9228        if (reason == null) {
9229            annotation = "Input dispatching timed out";
9230        } else {
9231            annotation = "Input dispatching timed out (" + reason + ")";
9232        }
9233
9234        if (proc != null) {
9235            synchronized (this) {
9236                if (proc.debugging) {
9237                    return false;
9238                }
9239
9240                if (mDidDexOpt) {
9241                    // Give more time since we were dexopting.
9242                    mDidDexOpt = false;
9243                    return false;
9244                }
9245
9246                if (proc.instrumentationClass != null) {
9247                    Bundle info = new Bundle();
9248                    info.putString("shortMsg", "keyDispatchingTimedOut");
9249                    info.putString("longMsg", annotation);
9250                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9251                    return true;
9252                }
9253            }
9254            mHandler.post(new Runnable() {
9255                @Override
9256                public void run() {
9257                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9258                }
9259            });
9260        }
9261
9262        return true;
9263    }
9264
9265    public Bundle getAssistContextExtras(int requestType) {
9266        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9267                "getAssistContextExtras()");
9268        PendingAssistExtras pae;
9269        Bundle extras = new Bundle();
9270        synchronized (this) {
9271            ActivityRecord activity = getFocusedStack().mResumedActivity;
9272            if (activity == null) {
9273                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9274                return null;
9275            }
9276            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9277            if (activity.app == null || activity.app.thread == null) {
9278                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9279                return extras;
9280            }
9281            if (activity.app.pid == Binder.getCallingPid()) {
9282                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9283                return extras;
9284            }
9285            pae = new PendingAssistExtras(activity);
9286            try {
9287                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9288                        requestType);
9289                mPendingAssistExtras.add(pae);
9290                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9291            } catch (RemoteException e) {
9292                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9293                return extras;
9294            }
9295        }
9296        synchronized (pae) {
9297            while (!pae.haveResult) {
9298                try {
9299                    pae.wait();
9300                } catch (InterruptedException e) {
9301                }
9302            }
9303            if (pae.result != null) {
9304                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9305            }
9306        }
9307        synchronized (this) {
9308            mPendingAssistExtras.remove(pae);
9309            mHandler.removeCallbacks(pae);
9310        }
9311        return extras;
9312    }
9313
9314    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9315        PendingAssistExtras pae = (PendingAssistExtras)token;
9316        synchronized (pae) {
9317            pae.result = extras;
9318            pae.haveResult = true;
9319            pae.notifyAll();
9320        }
9321    }
9322
9323    public void registerProcessObserver(IProcessObserver observer) {
9324        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9325                "registerProcessObserver()");
9326        synchronized (this) {
9327            mProcessObservers.register(observer);
9328        }
9329    }
9330
9331    @Override
9332    public void unregisterProcessObserver(IProcessObserver observer) {
9333        synchronized (this) {
9334            mProcessObservers.unregister(observer);
9335        }
9336    }
9337
9338    @Override
9339    public boolean convertFromTranslucent(IBinder token) {
9340        final long origId = Binder.clearCallingIdentity();
9341        try {
9342            synchronized (this) {
9343                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9344                if (r == null) {
9345                    return false;
9346                }
9347                if (r.changeWindowTranslucency(true)) {
9348                    mWindowManager.setAppFullscreen(token, true);
9349                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9350                    return true;
9351                }
9352                return false;
9353            }
9354        } finally {
9355            Binder.restoreCallingIdentity(origId);
9356        }
9357    }
9358
9359    @Override
9360    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9361        final long origId = Binder.clearCallingIdentity();
9362        try {
9363            synchronized (this) {
9364                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9365                if (r == null) {
9366                    return false;
9367                }
9368                if (r.changeWindowTranslucency(false)) {
9369                    r.task.stack.convertToTranslucent(r, options);
9370                    mWindowManager.setAppFullscreen(token, false);
9371                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9372                    return true;
9373                } else {
9374                    r.task.stack.mReturningActivityOptions = options;
9375                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9376                    return false;
9377                }
9378            }
9379        } finally {
9380            Binder.restoreCallingIdentity(origId);
9381        }
9382    }
9383
9384    @Override
9385    public ActivityOptions getActivityOptions(IBinder token) {
9386        final long origId = Binder.clearCallingIdentity();
9387        try {
9388            synchronized (this) {
9389                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9390                if (r != null) {
9391                    final ActivityOptions activityOptions = r.pendingOptions;
9392                    r.pendingOptions = null;
9393                    return activityOptions;
9394                }
9395                return null;
9396            }
9397        } finally {
9398            Binder.restoreCallingIdentity(origId);
9399        }
9400    }
9401
9402    @Override
9403    public void setImmersive(IBinder token, boolean immersive) {
9404        synchronized(this) {
9405            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9406            if (r == null) {
9407                throw new IllegalArgumentException();
9408            }
9409            r.immersive = immersive;
9410
9411            // update associated state if we're frontmost
9412            if (r == mFocusedActivity) {
9413                if (DEBUG_IMMERSIVE) {
9414                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9415                }
9416                applyUpdateLockStateLocked(r);
9417            }
9418        }
9419    }
9420
9421    @Override
9422    public boolean isImmersive(IBinder token) {
9423        synchronized (this) {
9424            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9425            if (r == null) {
9426                throw new IllegalArgumentException();
9427            }
9428            return r.immersive;
9429        }
9430    }
9431
9432    public boolean isTopActivityImmersive() {
9433        enforceNotIsolatedCaller("startActivity");
9434        synchronized (this) {
9435            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9436            return (r != null) ? r.immersive : false;
9437        }
9438    }
9439
9440    @Override
9441    public boolean isTopOfTask(IBinder token) {
9442        synchronized (this) {
9443            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9444            if (r == null) {
9445                throw new IllegalArgumentException();
9446            }
9447            return r.task.getTopActivity() == r;
9448        }
9449    }
9450
9451    public final void enterSafeMode() {
9452        synchronized(this) {
9453            // It only makes sense to do this before the system is ready
9454            // and started launching other packages.
9455            if (!mSystemReady) {
9456                try {
9457                    AppGlobals.getPackageManager().enterSafeMode();
9458                } catch (RemoteException e) {
9459                }
9460            }
9461
9462            mSafeMode = true;
9463        }
9464    }
9465
9466    public final void showSafeModeOverlay() {
9467        View v = LayoutInflater.from(mContext).inflate(
9468                com.android.internal.R.layout.safe_mode, null);
9469        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9470        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9471        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9472        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9473        lp.gravity = Gravity.BOTTOM | Gravity.START;
9474        lp.format = v.getBackground().getOpacity();
9475        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9476                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9477        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9478        ((WindowManager)mContext.getSystemService(
9479                Context.WINDOW_SERVICE)).addView(v, lp);
9480    }
9481
9482    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9483        if (!(sender instanceof PendingIntentRecord)) {
9484            return;
9485        }
9486        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9487        synchronized (stats) {
9488            if (mBatteryStatsService.isOnBattery()) {
9489                mBatteryStatsService.enforceCallingPermission();
9490                PendingIntentRecord rec = (PendingIntentRecord)sender;
9491                int MY_UID = Binder.getCallingUid();
9492                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9493                BatteryStatsImpl.Uid.Pkg pkg =
9494                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9495                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9496                pkg.incWakeupsLocked();
9497            }
9498        }
9499    }
9500
9501    public boolean killPids(int[] pids, String pReason, boolean secure) {
9502        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9503            throw new SecurityException("killPids only available to the system");
9504        }
9505        String reason = (pReason == null) ? "Unknown" : pReason;
9506        // XXX Note: don't acquire main activity lock here, because the window
9507        // manager calls in with its locks held.
9508
9509        boolean killed = false;
9510        synchronized (mPidsSelfLocked) {
9511            int[] types = new int[pids.length];
9512            int worstType = 0;
9513            for (int i=0; i<pids.length; i++) {
9514                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9515                if (proc != null) {
9516                    int type = proc.setAdj;
9517                    types[i] = type;
9518                    if (type > worstType) {
9519                        worstType = type;
9520                    }
9521                }
9522            }
9523
9524            // If the worst oom_adj is somewhere in the cached proc LRU range,
9525            // then constrain it so we will kill all cached procs.
9526            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9527                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9528                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9529            }
9530
9531            // If this is not a secure call, don't let it kill processes that
9532            // are important.
9533            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9534                worstType = ProcessList.SERVICE_ADJ;
9535            }
9536
9537            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9538            for (int i=0; i<pids.length; i++) {
9539                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9540                if (proc == null) {
9541                    continue;
9542                }
9543                int adj = proc.setAdj;
9544                if (adj >= worstType && !proc.killedByAm) {
9545                    killUnneededProcessLocked(proc, reason);
9546                    killed = true;
9547                }
9548            }
9549        }
9550        return killed;
9551    }
9552
9553    @Override
9554    public void killUid(int uid, String reason) {
9555        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9556            throw new SecurityException("killUid only available to the system");
9557        }
9558        synchronized (this) {
9559            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9560                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9561                    reason != null ? reason : "kill uid");
9562        }
9563    }
9564
9565    @Override
9566    public boolean killProcessesBelowForeground(String reason) {
9567        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9568            throw new SecurityException("killProcessesBelowForeground() only available to system");
9569        }
9570
9571        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9572    }
9573
9574    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9575        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9576            throw new SecurityException("killProcessesBelowAdj() only available to system");
9577        }
9578
9579        boolean killed = false;
9580        synchronized (mPidsSelfLocked) {
9581            final int size = mPidsSelfLocked.size();
9582            for (int i = 0; i < size; i++) {
9583                final int pid = mPidsSelfLocked.keyAt(i);
9584                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9585                if (proc == null) continue;
9586
9587                final int adj = proc.setAdj;
9588                if (adj > belowAdj && !proc.killedByAm) {
9589                    killUnneededProcessLocked(proc, reason);
9590                    killed = true;
9591                }
9592            }
9593        }
9594        return killed;
9595    }
9596
9597    @Override
9598    public void hang(final IBinder who, boolean allowRestart) {
9599        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9600                != PackageManager.PERMISSION_GRANTED) {
9601            throw new SecurityException("Requires permission "
9602                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9603        }
9604
9605        final IBinder.DeathRecipient death = new DeathRecipient() {
9606            @Override
9607            public void binderDied() {
9608                synchronized (this) {
9609                    notifyAll();
9610                }
9611            }
9612        };
9613
9614        try {
9615            who.linkToDeath(death, 0);
9616        } catch (RemoteException e) {
9617            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9618            return;
9619        }
9620
9621        synchronized (this) {
9622            Watchdog.getInstance().setAllowRestart(allowRestart);
9623            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9624            synchronized (death) {
9625                while (who.isBinderAlive()) {
9626                    try {
9627                        death.wait();
9628                    } catch (InterruptedException e) {
9629                    }
9630                }
9631            }
9632            Watchdog.getInstance().setAllowRestart(true);
9633        }
9634    }
9635
9636    @Override
9637    public void restart() {
9638        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9639                != PackageManager.PERMISSION_GRANTED) {
9640            throw new SecurityException("Requires permission "
9641                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9642        }
9643
9644        Log.i(TAG, "Sending shutdown broadcast...");
9645
9646        BroadcastReceiver br = new BroadcastReceiver() {
9647            @Override public void onReceive(Context context, Intent intent) {
9648                // Now the broadcast is done, finish up the low-level shutdown.
9649                Log.i(TAG, "Shutting down activity manager...");
9650                shutdown(10000);
9651                Log.i(TAG, "Shutdown complete, restarting!");
9652                Process.killProcess(Process.myPid());
9653                System.exit(10);
9654            }
9655        };
9656
9657        // First send the high-level shut down broadcast.
9658        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9659        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9660        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9661        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9662        mContext.sendOrderedBroadcastAsUser(intent,
9663                UserHandle.ALL, null, br, mHandler, 0, null, null);
9664        */
9665        br.onReceive(mContext, intent);
9666    }
9667
9668    private long getLowRamTimeSinceIdle(long now) {
9669        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9670    }
9671
9672    @Override
9673    public void performIdleMaintenance() {
9674        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9675                != PackageManager.PERMISSION_GRANTED) {
9676            throw new SecurityException("Requires permission "
9677                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9678        }
9679
9680        synchronized (this) {
9681            final long now = SystemClock.uptimeMillis();
9682            final long timeSinceLastIdle = now - mLastIdleTime;
9683            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9684            mLastIdleTime = now;
9685            mLowRamTimeSinceLastIdle = 0;
9686            if (mLowRamStartTime != 0) {
9687                mLowRamStartTime = now;
9688            }
9689
9690            StringBuilder sb = new StringBuilder(128);
9691            sb.append("Idle maintenance over ");
9692            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9693            sb.append(" low RAM for ");
9694            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9695            Slog.i(TAG, sb.toString());
9696
9697            // If at least 1/3 of our time since the last idle period has been spent
9698            // with RAM low, then we want to kill processes.
9699            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9700
9701            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9702                ProcessRecord proc = mLruProcesses.get(i);
9703                if (proc.notCachedSinceIdle) {
9704                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9705                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9706                        if (doKilling && proc.initialIdlePss != 0
9707                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9708                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9709                                    + " from " + proc.initialIdlePss + ")");
9710                        }
9711                    }
9712                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9713                    proc.notCachedSinceIdle = true;
9714                    proc.initialIdlePss = 0;
9715                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9716                            isSleeping(), now);
9717                }
9718            }
9719
9720            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9721            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9722        }
9723    }
9724
9725    private void retrieveSettings() {
9726        final ContentResolver resolver = mContext.getContentResolver();
9727        String debugApp = Settings.Global.getString(
9728            resolver, Settings.Global.DEBUG_APP);
9729        boolean waitForDebugger = Settings.Global.getInt(
9730            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9731        boolean alwaysFinishActivities = Settings.Global.getInt(
9732            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9733        boolean forceRtl = Settings.Global.getInt(
9734                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9735        // Transfer any global setting for forcing RTL layout, into a System Property
9736        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9737
9738        Configuration configuration = new Configuration();
9739        Settings.System.getConfiguration(resolver, configuration);
9740        if (forceRtl) {
9741            // This will take care of setting the correct layout direction flags
9742            configuration.setLayoutDirection(configuration.locale);
9743        }
9744
9745        synchronized (this) {
9746            mDebugApp = mOrigDebugApp = debugApp;
9747            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9748            mAlwaysFinishActivities = alwaysFinishActivities;
9749            // This happens before any activities are started, so we can
9750            // change mConfiguration in-place.
9751            updateConfigurationLocked(configuration, null, false, true);
9752            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9753        }
9754    }
9755
9756    public boolean testIsSystemReady() {
9757        // no need to synchronize(this) just to read & return the value
9758        return mSystemReady;
9759    }
9760
9761    private static File getCalledPreBootReceiversFile() {
9762        File dataDir = Environment.getDataDirectory();
9763        File systemDir = new File(dataDir, "system");
9764        File fname = new File(systemDir, "called_pre_boots.dat");
9765        return fname;
9766    }
9767
9768    static final int LAST_DONE_VERSION = 10000;
9769
9770    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9771        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9772        File file = getCalledPreBootReceiversFile();
9773        FileInputStream fis = null;
9774        try {
9775            fis = new FileInputStream(file);
9776            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9777            int fvers = dis.readInt();
9778            if (fvers == LAST_DONE_VERSION) {
9779                String vers = dis.readUTF();
9780                String codename = dis.readUTF();
9781                String build = dis.readUTF();
9782                if (android.os.Build.VERSION.RELEASE.equals(vers)
9783                        && android.os.Build.VERSION.CODENAME.equals(codename)
9784                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9785                    int num = dis.readInt();
9786                    while (num > 0) {
9787                        num--;
9788                        String pkg = dis.readUTF();
9789                        String cls = dis.readUTF();
9790                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9791                    }
9792                }
9793            }
9794        } catch (FileNotFoundException e) {
9795        } catch (IOException e) {
9796            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9797        } finally {
9798            if (fis != null) {
9799                try {
9800                    fis.close();
9801                } catch (IOException e) {
9802                }
9803            }
9804        }
9805        return lastDoneReceivers;
9806    }
9807
9808    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9809        File file = getCalledPreBootReceiversFile();
9810        FileOutputStream fos = null;
9811        DataOutputStream dos = null;
9812        try {
9813            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9814            fos = new FileOutputStream(file);
9815            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9816            dos.writeInt(LAST_DONE_VERSION);
9817            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9818            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9819            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9820            dos.writeInt(list.size());
9821            for (int i=0; i<list.size(); i++) {
9822                dos.writeUTF(list.get(i).getPackageName());
9823                dos.writeUTF(list.get(i).getClassName());
9824            }
9825        } catch (IOException e) {
9826            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9827            file.delete();
9828        } finally {
9829            FileUtils.sync(fos);
9830            if (dos != null) {
9831                try {
9832                    dos.close();
9833                } catch (IOException e) {
9834                    // TODO Auto-generated catch block
9835                    e.printStackTrace();
9836                }
9837            }
9838        }
9839    }
9840
9841    public void systemReady(final Runnable goingCallback) {
9842        synchronized(this) {
9843            if (mSystemReady) {
9844                if (goingCallback != null) goingCallback.run();
9845                return;
9846            }
9847
9848            if (mRecentTasks == null) {
9849                mRecentTasks = mTaskPersister.restoreTasksLocked();
9850                if (!mRecentTasks.isEmpty()) {
9851                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9852                }
9853                mTaskPersister.startPersisting();
9854            }
9855
9856            // Check to see if there are any update receivers to run.
9857            if (!mDidUpdate) {
9858                if (mWaitingUpdate) {
9859                    return;
9860                }
9861                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9862                List<ResolveInfo> ris = null;
9863                try {
9864                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9865                            intent, null, 0, 0);
9866                } catch (RemoteException e) {
9867                }
9868                if (ris != null) {
9869                    for (int i=ris.size()-1; i>=0; i--) {
9870                        if ((ris.get(i).activityInfo.applicationInfo.flags
9871                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9872                            ris.remove(i);
9873                        }
9874                    }
9875                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9876
9877                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9878
9879                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9880                    for (int i=0; i<ris.size(); i++) {
9881                        ActivityInfo ai = ris.get(i).activityInfo;
9882                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9883                        if (lastDoneReceivers.contains(comp)) {
9884                            // We already did the pre boot receiver for this app with the current
9885                            // platform version, so don't do it again...
9886                            ris.remove(i);
9887                            i--;
9888                            // ...however, do keep it as one that has been done, so we don't
9889                            // forget about it when rewriting the file of last done receivers.
9890                            doneReceivers.add(comp);
9891                        }
9892                    }
9893
9894                    final int[] users = getUsersLocked();
9895                    for (int i=0; i<ris.size(); i++) {
9896                        ActivityInfo ai = ris.get(i).activityInfo;
9897                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9898                        doneReceivers.add(comp);
9899                        intent.setComponent(comp);
9900                        for (int j=0; j<users.length; j++) {
9901                            IIntentReceiver finisher = null;
9902                            if (i == ris.size()-1 && j == users.length-1) {
9903                                finisher = new IIntentReceiver.Stub() {
9904                                    public void performReceive(Intent intent, int resultCode,
9905                                            String data, Bundle extras, boolean ordered,
9906                                            boolean sticky, int sendingUser) {
9907                                        // The raw IIntentReceiver interface is called
9908                                        // with the AM lock held, so redispatch to
9909                                        // execute our code without the lock.
9910                                        mHandler.post(new Runnable() {
9911                                            public void run() {
9912                                                synchronized (ActivityManagerService.this) {
9913                                                    mDidUpdate = true;
9914                                                }
9915                                                writeLastDonePreBootReceivers(doneReceivers);
9916                                                showBootMessage(mContext.getText(
9917                                                        R.string.android_upgrading_complete),
9918                                                        false);
9919                                                systemReady(goingCallback);
9920                                            }
9921                                        });
9922                                    }
9923                                };
9924                            }
9925                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9926                                    + " for user " + users[j]);
9927                            broadcastIntentLocked(null, null, intent, null, finisher,
9928                                    0, null, null, null, AppOpsManager.OP_NONE,
9929                                    true, false, MY_PID, Process.SYSTEM_UID,
9930                                    users[j]);
9931                            if (finisher != null) {
9932                                mWaitingUpdate = true;
9933                            }
9934                        }
9935                    }
9936                }
9937                if (mWaitingUpdate) {
9938                    return;
9939                }
9940                mDidUpdate = true;
9941            }
9942
9943            mAppOpsService.systemReady();
9944            mUsageStatsService.systemReady();
9945            mSystemReady = true;
9946        }
9947
9948        ArrayList<ProcessRecord> procsToKill = null;
9949        synchronized(mPidsSelfLocked) {
9950            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9951                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9952                if (!isAllowedWhileBooting(proc.info)){
9953                    if (procsToKill == null) {
9954                        procsToKill = new ArrayList<ProcessRecord>();
9955                    }
9956                    procsToKill.add(proc);
9957                }
9958            }
9959        }
9960
9961        synchronized(this) {
9962            if (procsToKill != null) {
9963                for (int i=procsToKill.size()-1; i>=0; i--) {
9964                    ProcessRecord proc = procsToKill.get(i);
9965                    Slog.i(TAG, "Removing system update proc: " + proc);
9966                    removeProcessLocked(proc, true, false, "system update done");
9967                }
9968            }
9969
9970            // Now that we have cleaned up any update processes, we
9971            // are ready to start launching real processes and know that
9972            // we won't trample on them any more.
9973            mProcessesReady = true;
9974        }
9975
9976        Slog.i(TAG, "System now ready");
9977        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9978            SystemClock.uptimeMillis());
9979
9980        synchronized(this) {
9981            // Make sure we have no pre-ready processes sitting around.
9982
9983            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9984                ResolveInfo ri = mContext.getPackageManager()
9985                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9986                                STOCK_PM_FLAGS);
9987                CharSequence errorMsg = null;
9988                if (ri != null) {
9989                    ActivityInfo ai = ri.activityInfo;
9990                    ApplicationInfo app = ai.applicationInfo;
9991                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9992                        mTopAction = Intent.ACTION_FACTORY_TEST;
9993                        mTopData = null;
9994                        mTopComponent = new ComponentName(app.packageName,
9995                                ai.name);
9996                    } else {
9997                        errorMsg = mContext.getResources().getText(
9998                                com.android.internal.R.string.factorytest_not_system);
9999                    }
10000                } else {
10001                    errorMsg = mContext.getResources().getText(
10002                            com.android.internal.R.string.factorytest_no_action);
10003                }
10004                if (errorMsg != null) {
10005                    mTopAction = null;
10006                    mTopData = null;
10007                    mTopComponent = null;
10008                    Message msg = Message.obtain();
10009                    msg.what = SHOW_FACTORY_ERROR_MSG;
10010                    msg.getData().putCharSequence("msg", errorMsg);
10011                    mHandler.sendMessage(msg);
10012                }
10013            }
10014        }
10015
10016        retrieveSettings();
10017
10018        synchronized (this) {
10019            readGrantedUriPermissionsLocked();
10020        }
10021
10022        if (goingCallback != null) goingCallback.run();
10023
10024        mSystemServiceManager.startUser(mCurrentUserId);
10025
10026        synchronized (this) {
10027            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10028                try {
10029                    List apps = AppGlobals.getPackageManager().
10030                        getPersistentApplications(STOCK_PM_FLAGS);
10031                    if (apps != null) {
10032                        int N = apps.size();
10033                        int i;
10034                        for (i=0; i<N; i++) {
10035                            ApplicationInfo info
10036                                = (ApplicationInfo)apps.get(i);
10037                            if (info != null &&
10038                                    !info.packageName.equals("android")) {
10039                                addAppLocked(info, false, null /* ABI override */);
10040                            }
10041                        }
10042                    }
10043                } catch (RemoteException ex) {
10044                    // pm is in same process, this will never happen.
10045                }
10046            }
10047
10048            // Start up initial activity.
10049            mBooting = true;
10050
10051            try {
10052                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10053                    Message msg = Message.obtain();
10054                    msg.what = SHOW_UID_ERROR_MSG;
10055                    mHandler.sendMessage(msg);
10056                }
10057            } catch (RemoteException e) {
10058            }
10059
10060            long ident = Binder.clearCallingIdentity();
10061            try {
10062                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10063                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10064                        | Intent.FLAG_RECEIVER_FOREGROUND);
10065                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10066                broadcastIntentLocked(null, null, intent,
10067                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10068                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10069                intent = new Intent(Intent.ACTION_USER_STARTING);
10070                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10071                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10072                broadcastIntentLocked(null, null, intent,
10073                        null, new IIntentReceiver.Stub() {
10074                            @Override
10075                            public void performReceive(Intent intent, int resultCode, String data,
10076                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10077                                    throws RemoteException {
10078                            }
10079                        }, 0, null, null,
10080                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10081                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10082            } catch (Throwable t) {
10083                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10084            } finally {
10085                Binder.restoreCallingIdentity(ident);
10086            }
10087            mStackSupervisor.resumeTopActivitiesLocked();
10088            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10089        }
10090    }
10091
10092    private boolean makeAppCrashingLocked(ProcessRecord app,
10093            String shortMsg, String longMsg, String stackTrace) {
10094        app.crashing = true;
10095        app.crashingReport = generateProcessError(app,
10096                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10097        startAppProblemLocked(app);
10098        app.stopFreezingAllLocked();
10099        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10100    }
10101
10102    private void makeAppNotRespondingLocked(ProcessRecord app,
10103            String activity, String shortMsg, String longMsg) {
10104        app.notResponding = true;
10105        app.notRespondingReport = generateProcessError(app,
10106                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10107                activity, shortMsg, longMsg, null);
10108        startAppProblemLocked(app);
10109        app.stopFreezingAllLocked();
10110    }
10111
10112    /**
10113     * Generate a process error record, suitable for attachment to a ProcessRecord.
10114     *
10115     * @param app The ProcessRecord in which the error occurred.
10116     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10117     *                      ActivityManager.AppErrorStateInfo
10118     * @param activity The activity associated with the crash, if known.
10119     * @param shortMsg Short message describing the crash.
10120     * @param longMsg Long message describing the crash.
10121     * @param stackTrace Full crash stack trace, may be null.
10122     *
10123     * @return Returns a fully-formed AppErrorStateInfo record.
10124     */
10125    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10126            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10127        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10128
10129        report.condition = condition;
10130        report.processName = app.processName;
10131        report.pid = app.pid;
10132        report.uid = app.info.uid;
10133        report.tag = activity;
10134        report.shortMsg = shortMsg;
10135        report.longMsg = longMsg;
10136        report.stackTrace = stackTrace;
10137
10138        return report;
10139    }
10140
10141    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10142        synchronized (this) {
10143            app.crashing = false;
10144            app.crashingReport = null;
10145            app.notResponding = false;
10146            app.notRespondingReport = null;
10147            if (app.anrDialog == fromDialog) {
10148                app.anrDialog = null;
10149            }
10150            if (app.waitDialog == fromDialog) {
10151                app.waitDialog = null;
10152            }
10153            if (app.pid > 0 && app.pid != MY_PID) {
10154                handleAppCrashLocked(app, null, null, null);
10155                killUnneededProcessLocked(app, "user request after error");
10156            }
10157        }
10158    }
10159
10160    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10161            String stackTrace) {
10162        long now = SystemClock.uptimeMillis();
10163
10164        Long crashTime;
10165        if (!app.isolated) {
10166            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10167        } else {
10168            crashTime = null;
10169        }
10170        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10171            // This process loses!
10172            Slog.w(TAG, "Process " + app.info.processName
10173                    + " has crashed too many times: killing!");
10174            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10175                    app.userId, app.info.processName, app.uid);
10176            mStackSupervisor.handleAppCrashLocked(app);
10177            if (!app.persistent) {
10178                // We don't want to start this process again until the user
10179                // explicitly does so...  but for persistent process, we really
10180                // need to keep it running.  If a persistent process is actually
10181                // repeatedly crashing, then badness for everyone.
10182                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10183                        app.info.processName);
10184                if (!app.isolated) {
10185                    // XXX We don't have a way to mark isolated processes
10186                    // as bad, since they don't have a peristent identity.
10187                    mBadProcesses.put(app.info.processName, app.uid,
10188                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10189                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10190                }
10191                app.bad = true;
10192                app.removed = true;
10193                // Don't let services in this process be restarted and potentially
10194                // annoy the user repeatedly.  Unless it is persistent, since those
10195                // processes run critical code.
10196                removeProcessLocked(app, false, false, "crash");
10197                mStackSupervisor.resumeTopActivitiesLocked();
10198                return false;
10199            }
10200            mStackSupervisor.resumeTopActivitiesLocked();
10201        } else {
10202            mStackSupervisor.finishTopRunningActivityLocked(app);
10203        }
10204
10205        // Bump up the crash count of any services currently running in the proc.
10206        for (int i=app.services.size()-1; i>=0; i--) {
10207            // Any services running in the application need to be placed
10208            // back in the pending list.
10209            ServiceRecord sr = app.services.valueAt(i);
10210            sr.crashCount++;
10211        }
10212
10213        // If the crashing process is what we consider to be the "home process" and it has been
10214        // replaced by a third-party app, clear the package preferred activities from packages
10215        // with a home activity running in the process to prevent a repeatedly crashing app
10216        // from blocking the user to manually clear the list.
10217        final ArrayList<ActivityRecord> activities = app.activities;
10218        if (app == mHomeProcess && activities.size() > 0
10219                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10220            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10221                final ActivityRecord r = activities.get(activityNdx);
10222                if (r.isHomeActivity()) {
10223                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10224                    try {
10225                        ActivityThread.getPackageManager()
10226                                .clearPackagePreferredActivities(r.packageName);
10227                    } catch (RemoteException c) {
10228                        // pm is in same process, this will never happen.
10229                    }
10230                }
10231            }
10232        }
10233
10234        if (!app.isolated) {
10235            // XXX Can't keep track of crash times for isolated processes,
10236            // because they don't have a perisistent identity.
10237            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10238        }
10239
10240        return true;
10241    }
10242
10243    void startAppProblemLocked(ProcessRecord app) {
10244        if (app.userId == mCurrentUserId) {
10245            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10246                    mContext, app.info.packageName, app.info.flags);
10247        } else {
10248            // If this app is not running under the current user, then we
10249            // can't give it a report button because that would require
10250            // launching the report UI under a different user.
10251            app.errorReportReceiver = null;
10252        }
10253        skipCurrentReceiverLocked(app);
10254    }
10255
10256    void skipCurrentReceiverLocked(ProcessRecord app) {
10257        for (BroadcastQueue queue : mBroadcastQueues) {
10258            queue.skipCurrentReceiverLocked(app);
10259        }
10260    }
10261
10262    /**
10263     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10264     * The application process will exit immediately after this call returns.
10265     * @param app object of the crashing app, null for the system server
10266     * @param crashInfo describing the exception
10267     */
10268    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10269        ProcessRecord r = findAppProcess(app, "Crash");
10270        final String processName = app == null ? "system_server"
10271                : (r == null ? "unknown" : r.processName);
10272
10273        handleApplicationCrashInner("crash", r, processName, crashInfo);
10274    }
10275
10276    /* Native crash reporting uses this inner version because it needs to be somewhat
10277     * decoupled from the AM-managed cleanup lifecycle
10278     */
10279    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10280            ApplicationErrorReport.CrashInfo crashInfo) {
10281        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10282                UserHandle.getUserId(Binder.getCallingUid()), processName,
10283                r == null ? -1 : r.info.flags,
10284                crashInfo.exceptionClassName,
10285                crashInfo.exceptionMessage,
10286                crashInfo.throwFileName,
10287                crashInfo.throwLineNumber);
10288
10289        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10290
10291        crashApplication(r, crashInfo);
10292    }
10293
10294    public void handleApplicationStrictModeViolation(
10295            IBinder app,
10296            int violationMask,
10297            StrictMode.ViolationInfo info) {
10298        ProcessRecord r = findAppProcess(app, "StrictMode");
10299        if (r == null) {
10300            return;
10301        }
10302
10303        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10304            Integer stackFingerprint = info.hashCode();
10305            boolean logIt = true;
10306            synchronized (mAlreadyLoggedViolatedStacks) {
10307                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10308                    logIt = false;
10309                    // TODO: sub-sample into EventLog for these, with
10310                    // the info.durationMillis?  Then we'd get
10311                    // the relative pain numbers, without logging all
10312                    // the stack traces repeatedly.  We'd want to do
10313                    // likewise in the client code, which also does
10314                    // dup suppression, before the Binder call.
10315                } else {
10316                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10317                        mAlreadyLoggedViolatedStacks.clear();
10318                    }
10319                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10320                }
10321            }
10322            if (logIt) {
10323                logStrictModeViolationToDropBox(r, info);
10324            }
10325        }
10326
10327        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10328            AppErrorResult result = new AppErrorResult();
10329            synchronized (this) {
10330                final long origId = Binder.clearCallingIdentity();
10331
10332                Message msg = Message.obtain();
10333                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10334                HashMap<String, Object> data = new HashMap<String, Object>();
10335                data.put("result", result);
10336                data.put("app", r);
10337                data.put("violationMask", violationMask);
10338                data.put("info", info);
10339                msg.obj = data;
10340                mHandler.sendMessage(msg);
10341
10342                Binder.restoreCallingIdentity(origId);
10343            }
10344            int res = result.get();
10345            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10346        }
10347    }
10348
10349    // Depending on the policy in effect, there could be a bunch of
10350    // these in quick succession so we try to batch these together to
10351    // minimize disk writes, number of dropbox entries, and maximize
10352    // compression, by having more fewer, larger records.
10353    private void logStrictModeViolationToDropBox(
10354            ProcessRecord process,
10355            StrictMode.ViolationInfo info) {
10356        if (info == null) {
10357            return;
10358        }
10359        final boolean isSystemApp = process == null ||
10360                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10361                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10362        final String processName = process == null ? "unknown" : process.processName;
10363        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10364        final DropBoxManager dbox = (DropBoxManager)
10365                mContext.getSystemService(Context.DROPBOX_SERVICE);
10366
10367        // Exit early if the dropbox isn't configured to accept this report type.
10368        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10369
10370        boolean bufferWasEmpty;
10371        boolean needsFlush;
10372        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10373        synchronized (sb) {
10374            bufferWasEmpty = sb.length() == 0;
10375            appendDropBoxProcessHeaders(process, processName, sb);
10376            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10377            sb.append("System-App: ").append(isSystemApp).append("\n");
10378            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10379            if (info.violationNumThisLoop != 0) {
10380                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10381            }
10382            if (info.numAnimationsRunning != 0) {
10383                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10384            }
10385            if (info.broadcastIntentAction != null) {
10386                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10387            }
10388            if (info.durationMillis != -1) {
10389                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10390            }
10391            if (info.numInstances != -1) {
10392                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10393            }
10394            if (info.tags != null) {
10395                for (String tag : info.tags) {
10396                    sb.append("Span-Tag: ").append(tag).append("\n");
10397                }
10398            }
10399            sb.append("\n");
10400            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10401                sb.append(info.crashInfo.stackTrace);
10402            }
10403            sb.append("\n");
10404
10405            // Only buffer up to ~64k.  Various logging bits truncate
10406            // things at 128k.
10407            needsFlush = (sb.length() > 64 * 1024);
10408        }
10409
10410        // Flush immediately if the buffer's grown too large, or this
10411        // is a non-system app.  Non-system apps are isolated with a
10412        // different tag & policy and not batched.
10413        //
10414        // Batching is useful during internal testing with
10415        // StrictMode settings turned up high.  Without batching,
10416        // thousands of separate files could be created on boot.
10417        if (!isSystemApp || needsFlush) {
10418            new Thread("Error dump: " + dropboxTag) {
10419                @Override
10420                public void run() {
10421                    String report;
10422                    synchronized (sb) {
10423                        report = sb.toString();
10424                        sb.delete(0, sb.length());
10425                        sb.trimToSize();
10426                    }
10427                    if (report.length() != 0) {
10428                        dbox.addText(dropboxTag, report);
10429                    }
10430                }
10431            }.start();
10432            return;
10433        }
10434
10435        // System app batching:
10436        if (!bufferWasEmpty) {
10437            // An existing dropbox-writing thread is outstanding, so
10438            // we don't need to start it up.  The existing thread will
10439            // catch the buffer appends we just did.
10440            return;
10441        }
10442
10443        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10444        // (After this point, we shouldn't access AMS internal data structures.)
10445        new Thread("Error dump: " + dropboxTag) {
10446            @Override
10447            public void run() {
10448                // 5 second sleep to let stacks arrive and be batched together
10449                try {
10450                    Thread.sleep(5000);  // 5 seconds
10451                } catch (InterruptedException e) {}
10452
10453                String errorReport;
10454                synchronized (mStrictModeBuffer) {
10455                    errorReport = mStrictModeBuffer.toString();
10456                    if (errorReport.length() == 0) {
10457                        return;
10458                    }
10459                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10460                    mStrictModeBuffer.trimToSize();
10461                }
10462                dbox.addText(dropboxTag, errorReport);
10463            }
10464        }.start();
10465    }
10466
10467    /**
10468     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10469     * @param app object of the crashing app, null for the system server
10470     * @param tag reported by the caller
10471     * @param crashInfo describing the context of the error
10472     * @return true if the process should exit immediately (WTF is fatal)
10473     */
10474    public boolean handleApplicationWtf(IBinder app, String tag,
10475            ApplicationErrorReport.CrashInfo crashInfo) {
10476        ProcessRecord r = findAppProcess(app, "WTF");
10477        final String processName = app == null ? "system_server"
10478                : (r == null ? "unknown" : r.processName);
10479
10480        EventLog.writeEvent(EventLogTags.AM_WTF,
10481                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10482                processName,
10483                r == null ? -1 : r.info.flags,
10484                tag, crashInfo.exceptionMessage);
10485
10486        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10487
10488        if (r != null && r.pid != Process.myPid() &&
10489                Settings.Global.getInt(mContext.getContentResolver(),
10490                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10491            crashApplication(r, crashInfo);
10492            return true;
10493        } else {
10494            return false;
10495        }
10496    }
10497
10498    /**
10499     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10500     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10501     */
10502    private ProcessRecord findAppProcess(IBinder app, String reason) {
10503        if (app == null) {
10504            return null;
10505        }
10506
10507        synchronized (this) {
10508            final int NP = mProcessNames.getMap().size();
10509            for (int ip=0; ip<NP; ip++) {
10510                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10511                final int NA = apps.size();
10512                for (int ia=0; ia<NA; ia++) {
10513                    ProcessRecord p = apps.valueAt(ia);
10514                    if (p.thread != null && p.thread.asBinder() == app) {
10515                        return p;
10516                    }
10517                }
10518            }
10519
10520            Slog.w(TAG, "Can't find mystery application for " + reason
10521                    + " from pid=" + Binder.getCallingPid()
10522                    + " uid=" + Binder.getCallingUid() + ": " + app);
10523            return null;
10524        }
10525    }
10526
10527    /**
10528     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10529     * to append various headers to the dropbox log text.
10530     */
10531    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10532            StringBuilder sb) {
10533        // Watchdog thread ends up invoking this function (with
10534        // a null ProcessRecord) to add the stack file to dropbox.
10535        // Do not acquire a lock on this (am) in such cases, as it
10536        // could cause a potential deadlock, if and when watchdog
10537        // is invoked due to unavailability of lock on am and it
10538        // would prevent watchdog from killing system_server.
10539        if (process == null) {
10540            sb.append("Process: ").append(processName).append("\n");
10541            return;
10542        }
10543        // Note: ProcessRecord 'process' is guarded by the service
10544        // instance.  (notably process.pkgList, which could otherwise change
10545        // concurrently during execution of this method)
10546        synchronized (this) {
10547            sb.append("Process: ").append(processName).append("\n");
10548            int flags = process.info.flags;
10549            IPackageManager pm = AppGlobals.getPackageManager();
10550            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10551            for (int ip=0; ip<process.pkgList.size(); ip++) {
10552                String pkg = process.pkgList.keyAt(ip);
10553                sb.append("Package: ").append(pkg);
10554                try {
10555                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10556                    if (pi != null) {
10557                        sb.append(" v").append(pi.versionCode);
10558                        if (pi.versionName != null) {
10559                            sb.append(" (").append(pi.versionName).append(")");
10560                        }
10561                    }
10562                } catch (RemoteException e) {
10563                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10564                }
10565                sb.append("\n");
10566            }
10567        }
10568    }
10569
10570    private static String processClass(ProcessRecord process) {
10571        if (process == null || process.pid == MY_PID) {
10572            return "system_server";
10573        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10574            return "system_app";
10575        } else {
10576            return "data_app";
10577        }
10578    }
10579
10580    /**
10581     * Write a description of an error (crash, WTF, ANR) to the drop box.
10582     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10583     * @param process which caused the error, null means the system server
10584     * @param activity which triggered the error, null if unknown
10585     * @param parent activity related to the error, null if unknown
10586     * @param subject line related to the error, null if absent
10587     * @param report in long form describing the error, null if absent
10588     * @param logFile to include in the report, null if none
10589     * @param crashInfo giving an application stack trace, null if absent
10590     */
10591    public void addErrorToDropBox(String eventType,
10592            ProcessRecord process, String processName, ActivityRecord activity,
10593            ActivityRecord parent, String subject,
10594            final String report, final File logFile,
10595            final ApplicationErrorReport.CrashInfo crashInfo) {
10596        // NOTE -- this must never acquire the ActivityManagerService lock,
10597        // otherwise the watchdog may be prevented from resetting the system.
10598
10599        final String dropboxTag = processClass(process) + "_" + eventType;
10600        final DropBoxManager dbox = (DropBoxManager)
10601                mContext.getSystemService(Context.DROPBOX_SERVICE);
10602
10603        // Exit early if the dropbox isn't configured to accept this report type.
10604        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10605
10606        final StringBuilder sb = new StringBuilder(1024);
10607        appendDropBoxProcessHeaders(process, processName, sb);
10608        if (activity != null) {
10609            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10610        }
10611        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10612            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10613        }
10614        if (parent != null && parent != activity) {
10615            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10616        }
10617        if (subject != null) {
10618            sb.append("Subject: ").append(subject).append("\n");
10619        }
10620        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10621        if (Debug.isDebuggerConnected()) {
10622            sb.append("Debugger: Connected\n");
10623        }
10624        sb.append("\n");
10625
10626        // Do the rest in a worker thread to avoid blocking the caller on I/O
10627        // (After this point, we shouldn't access AMS internal data structures.)
10628        Thread worker = new Thread("Error dump: " + dropboxTag) {
10629            @Override
10630            public void run() {
10631                if (report != null) {
10632                    sb.append(report);
10633                }
10634                if (logFile != null) {
10635                    try {
10636                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10637                                    "\n\n[[TRUNCATED]]"));
10638                    } catch (IOException e) {
10639                        Slog.e(TAG, "Error reading " + logFile, e);
10640                    }
10641                }
10642                if (crashInfo != null && crashInfo.stackTrace != null) {
10643                    sb.append(crashInfo.stackTrace);
10644                }
10645
10646                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10647                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10648                if (lines > 0) {
10649                    sb.append("\n");
10650
10651                    // Merge several logcat streams, and take the last N lines
10652                    InputStreamReader input = null;
10653                    try {
10654                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10655                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10656                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10657
10658                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10659                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10660                        input = new InputStreamReader(logcat.getInputStream());
10661
10662                        int num;
10663                        char[] buf = new char[8192];
10664                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10665                    } catch (IOException e) {
10666                        Slog.e(TAG, "Error running logcat", e);
10667                    } finally {
10668                        if (input != null) try { input.close(); } catch (IOException e) {}
10669                    }
10670                }
10671
10672                dbox.addText(dropboxTag, sb.toString());
10673            }
10674        };
10675
10676        if (process == null) {
10677            // If process is null, we are being called from some internal code
10678            // and may be about to die -- run this synchronously.
10679            worker.run();
10680        } else {
10681            worker.start();
10682        }
10683    }
10684
10685    /**
10686     * Bring up the "unexpected error" dialog box for a crashing app.
10687     * Deal with edge cases (intercepts from instrumented applications,
10688     * ActivityController, error intent receivers, that sort of thing).
10689     * @param r the application crashing
10690     * @param crashInfo describing the failure
10691     */
10692    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10693        long timeMillis = System.currentTimeMillis();
10694        String shortMsg = crashInfo.exceptionClassName;
10695        String longMsg = crashInfo.exceptionMessage;
10696        String stackTrace = crashInfo.stackTrace;
10697        if (shortMsg != null && longMsg != null) {
10698            longMsg = shortMsg + ": " + longMsg;
10699        } else if (shortMsg != null) {
10700            longMsg = shortMsg;
10701        }
10702
10703        AppErrorResult result = new AppErrorResult();
10704        synchronized (this) {
10705            if (mController != null) {
10706                try {
10707                    String name = r != null ? r.processName : null;
10708                    int pid = r != null ? r.pid : Binder.getCallingPid();
10709                    if (!mController.appCrashed(name, pid,
10710                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10711                        Slog.w(TAG, "Force-killing crashed app " + name
10712                                + " at watcher's request");
10713                        Process.killProcess(pid);
10714                        return;
10715                    }
10716                } catch (RemoteException e) {
10717                    mController = null;
10718                    Watchdog.getInstance().setActivityController(null);
10719                }
10720            }
10721
10722            final long origId = Binder.clearCallingIdentity();
10723
10724            // If this process is running instrumentation, finish it.
10725            if (r != null && r.instrumentationClass != null) {
10726                Slog.w(TAG, "Error in app " + r.processName
10727                      + " running instrumentation " + r.instrumentationClass + ":");
10728                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10729                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10730                Bundle info = new Bundle();
10731                info.putString("shortMsg", shortMsg);
10732                info.putString("longMsg", longMsg);
10733                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10734                Binder.restoreCallingIdentity(origId);
10735                return;
10736            }
10737
10738            // If we can't identify the process or it's already exceeded its crash quota,
10739            // quit right away without showing a crash dialog.
10740            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10741                Binder.restoreCallingIdentity(origId);
10742                return;
10743            }
10744
10745            Message msg = Message.obtain();
10746            msg.what = SHOW_ERROR_MSG;
10747            HashMap data = new HashMap();
10748            data.put("result", result);
10749            data.put("app", r);
10750            msg.obj = data;
10751            mHandler.sendMessage(msg);
10752
10753            Binder.restoreCallingIdentity(origId);
10754        }
10755
10756        int res = result.get();
10757
10758        Intent appErrorIntent = null;
10759        synchronized (this) {
10760            if (r != null && !r.isolated) {
10761                // XXX Can't keep track of crash time for isolated processes,
10762                // since they don't have a persistent identity.
10763                mProcessCrashTimes.put(r.info.processName, r.uid,
10764                        SystemClock.uptimeMillis());
10765            }
10766            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10767                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10768            }
10769        }
10770
10771        if (appErrorIntent != null) {
10772            try {
10773                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10774            } catch (ActivityNotFoundException e) {
10775                Slog.w(TAG, "bug report receiver dissappeared", e);
10776            }
10777        }
10778    }
10779
10780    Intent createAppErrorIntentLocked(ProcessRecord r,
10781            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10782        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10783        if (report == null) {
10784            return null;
10785        }
10786        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10787        result.setComponent(r.errorReportReceiver);
10788        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10789        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10790        return result;
10791    }
10792
10793    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10794            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10795        if (r.errorReportReceiver == null) {
10796            return null;
10797        }
10798
10799        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10800            return null;
10801        }
10802
10803        ApplicationErrorReport report = new ApplicationErrorReport();
10804        report.packageName = r.info.packageName;
10805        report.installerPackageName = r.errorReportReceiver.getPackageName();
10806        report.processName = r.processName;
10807        report.time = timeMillis;
10808        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10809
10810        if (r.crashing || r.forceCrashReport) {
10811            report.type = ApplicationErrorReport.TYPE_CRASH;
10812            report.crashInfo = crashInfo;
10813        } else if (r.notResponding) {
10814            report.type = ApplicationErrorReport.TYPE_ANR;
10815            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10816
10817            report.anrInfo.activity = r.notRespondingReport.tag;
10818            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10819            report.anrInfo.info = r.notRespondingReport.longMsg;
10820        }
10821
10822        return report;
10823    }
10824
10825    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10826        enforceNotIsolatedCaller("getProcessesInErrorState");
10827        // assume our apps are happy - lazy create the list
10828        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10829
10830        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10831                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10832        int userId = UserHandle.getUserId(Binder.getCallingUid());
10833
10834        synchronized (this) {
10835
10836            // iterate across all processes
10837            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10838                ProcessRecord app = mLruProcesses.get(i);
10839                if (!allUsers && app.userId != userId) {
10840                    continue;
10841                }
10842                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10843                    // This one's in trouble, so we'll generate a report for it
10844                    // crashes are higher priority (in case there's a crash *and* an anr)
10845                    ActivityManager.ProcessErrorStateInfo report = null;
10846                    if (app.crashing) {
10847                        report = app.crashingReport;
10848                    } else if (app.notResponding) {
10849                        report = app.notRespondingReport;
10850                    }
10851
10852                    if (report != null) {
10853                        if (errList == null) {
10854                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10855                        }
10856                        errList.add(report);
10857                    } else {
10858                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10859                                " crashing = " + app.crashing +
10860                                " notResponding = " + app.notResponding);
10861                    }
10862                }
10863            }
10864        }
10865
10866        return errList;
10867    }
10868
10869    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10870        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10871            if (currApp != null) {
10872                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10873            }
10874            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10875        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10876            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10877        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10878            if (currApp != null) {
10879                currApp.lru = 0;
10880            }
10881            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10882        } else if (adj >= ProcessList.SERVICE_ADJ) {
10883            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10884        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10885            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10886        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10887            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10888        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10889            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10890        } else {
10891            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10892        }
10893    }
10894
10895    private void fillInProcMemInfo(ProcessRecord app,
10896            ActivityManager.RunningAppProcessInfo outInfo) {
10897        outInfo.pid = app.pid;
10898        outInfo.uid = app.info.uid;
10899        if (mHeavyWeightProcess == app) {
10900            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10901        }
10902        if (app.persistent) {
10903            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10904        }
10905        if (app.activities.size() > 0) {
10906            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10907        }
10908        outInfo.lastTrimLevel = app.trimMemoryLevel;
10909        int adj = app.curAdj;
10910        outInfo.importance = oomAdjToImportance(adj, outInfo);
10911        outInfo.importanceReasonCode = app.adjTypeCode;
10912        outInfo.processState = app.curProcState;
10913    }
10914
10915    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10916        enforceNotIsolatedCaller("getRunningAppProcesses");
10917        // Lazy instantiation of list
10918        List<ActivityManager.RunningAppProcessInfo> runList = null;
10919        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10920                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10921        int userId = UserHandle.getUserId(Binder.getCallingUid());
10922        synchronized (this) {
10923            // Iterate across all processes
10924            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10925                ProcessRecord app = mLruProcesses.get(i);
10926                if (!allUsers && app.userId != userId) {
10927                    continue;
10928                }
10929                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10930                    // Generate process state info for running application
10931                    ActivityManager.RunningAppProcessInfo currApp =
10932                        new ActivityManager.RunningAppProcessInfo(app.processName,
10933                                app.pid, app.getPackageList());
10934                    fillInProcMemInfo(app, currApp);
10935                    if (app.adjSource instanceof ProcessRecord) {
10936                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10937                        currApp.importanceReasonImportance = oomAdjToImportance(
10938                                app.adjSourceOom, null);
10939                    } else if (app.adjSource instanceof ActivityRecord) {
10940                        ActivityRecord r = (ActivityRecord)app.adjSource;
10941                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10942                    }
10943                    if (app.adjTarget instanceof ComponentName) {
10944                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10945                    }
10946                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10947                    //        + " lru=" + currApp.lru);
10948                    if (runList == null) {
10949                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10950                    }
10951                    runList.add(currApp);
10952                }
10953            }
10954        }
10955        return runList;
10956    }
10957
10958    public List<ApplicationInfo> getRunningExternalApplications() {
10959        enforceNotIsolatedCaller("getRunningExternalApplications");
10960        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10961        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10962        if (runningApps != null && runningApps.size() > 0) {
10963            Set<String> extList = new HashSet<String>();
10964            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10965                if (app.pkgList != null) {
10966                    for (String pkg : app.pkgList) {
10967                        extList.add(pkg);
10968                    }
10969                }
10970            }
10971            IPackageManager pm = AppGlobals.getPackageManager();
10972            for (String pkg : extList) {
10973                try {
10974                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10975                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10976                        retList.add(info);
10977                    }
10978                } catch (RemoteException e) {
10979                }
10980            }
10981        }
10982        return retList;
10983    }
10984
10985    @Override
10986    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10987        enforceNotIsolatedCaller("getMyMemoryState");
10988        synchronized (this) {
10989            ProcessRecord proc;
10990            synchronized (mPidsSelfLocked) {
10991                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10992            }
10993            fillInProcMemInfo(proc, outInfo);
10994        }
10995    }
10996
10997    @Override
10998    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10999        if (checkCallingPermission(android.Manifest.permission.DUMP)
11000                != PackageManager.PERMISSION_GRANTED) {
11001            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11002                    + Binder.getCallingPid()
11003                    + ", uid=" + Binder.getCallingUid()
11004                    + " without permission "
11005                    + android.Manifest.permission.DUMP);
11006            return;
11007        }
11008
11009        boolean dumpAll = false;
11010        boolean dumpClient = false;
11011        String dumpPackage = null;
11012
11013        int opti = 0;
11014        while (opti < args.length) {
11015            String opt = args[opti];
11016            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11017                break;
11018            }
11019            opti++;
11020            if ("-a".equals(opt)) {
11021                dumpAll = true;
11022            } else if ("-c".equals(opt)) {
11023                dumpClient = true;
11024            } else if ("-h".equals(opt)) {
11025                pw.println("Activity manager dump options:");
11026                pw.println("  [-a] [-c] [-h] [cmd] ...");
11027                pw.println("  cmd may be one of:");
11028                pw.println("    a[ctivities]: activity stack state");
11029                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11030                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11031                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11032                pw.println("    o[om]: out of memory management");
11033                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11034                pw.println("    provider [COMP_SPEC]: provider client-side state");
11035                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11036                pw.println("    service [COMP_SPEC]: service client-side state");
11037                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11038                pw.println("    all: dump all activities");
11039                pw.println("    top: dump the top activity");
11040                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11041                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11042                pw.println("    a partial substring in a component name, a");
11043                pw.println("    hex object identifier.");
11044                pw.println("  -a: include all available server state.");
11045                pw.println("  -c: include client state.");
11046                return;
11047            } else {
11048                pw.println("Unknown argument: " + opt + "; use -h for help");
11049            }
11050        }
11051
11052        long origId = Binder.clearCallingIdentity();
11053        boolean more = false;
11054        // Is the caller requesting to dump a particular piece of data?
11055        if (opti < args.length) {
11056            String cmd = args[opti];
11057            opti++;
11058            if ("activities".equals(cmd) || "a".equals(cmd)) {
11059                synchronized (this) {
11060                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11061                }
11062            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11063                String[] newArgs;
11064                String name;
11065                if (opti >= args.length) {
11066                    name = null;
11067                    newArgs = EMPTY_STRING_ARRAY;
11068                } else {
11069                    name = args[opti];
11070                    opti++;
11071                    newArgs = new String[args.length - opti];
11072                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11073                            args.length - opti);
11074                }
11075                synchronized (this) {
11076                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11077                }
11078            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11079                String[] newArgs;
11080                String name;
11081                if (opti >= args.length) {
11082                    name = null;
11083                    newArgs = EMPTY_STRING_ARRAY;
11084                } else {
11085                    name = args[opti];
11086                    opti++;
11087                    newArgs = new String[args.length - opti];
11088                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11089                            args.length - opti);
11090                }
11091                synchronized (this) {
11092                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11093                }
11094            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11095                String[] newArgs;
11096                String name;
11097                if (opti >= args.length) {
11098                    name = null;
11099                    newArgs = EMPTY_STRING_ARRAY;
11100                } else {
11101                    name = args[opti];
11102                    opti++;
11103                    newArgs = new String[args.length - opti];
11104                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11105                            args.length - opti);
11106                }
11107                synchronized (this) {
11108                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11109                }
11110            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11111                synchronized (this) {
11112                    dumpOomLocked(fd, pw, args, opti, true);
11113                }
11114            } else if ("provider".equals(cmd)) {
11115                String[] newArgs;
11116                String name;
11117                if (opti >= args.length) {
11118                    name = null;
11119                    newArgs = EMPTY_STRING_ARRAY;
11120                } else {
11121                    name = args[opti];
11122                    opti++;
11123                    newArgs = new String[args.length - opti];
11124                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11125                }
11126                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11127                    pw.println("No providers match: " + name);
11128                    pw.println("Use -h for help.");
11129                }
11130            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11131                synchronized (this) {
11132                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11133                }
11134            } else if ("service".equals(cmd)) {
11135                String[] newArgs;
11136                String name;
11137                if (opti >= args.length) {
11138                    name = null;
11139                    newArgs = EMPTY_STRING_ARRAY;
11140                } else {
11141                    name = args[opti];
11142                    opti++;
11143                    newArgs = new String[args.length - opti];
11144                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11145                            args.length - opti);
11146                }
11147                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11148                    pw.println("No services match: " + name);
11149                    pw.println("Use -h for help.");
11150                }
11151            } else if ("package".equals(cmd)) {
11152                String[] newArgs;
11153                if (opti >= args.length) {
11154                    pw.println("package: no package name specified");
11155                    pw.println("Use -h for help.");
11156                } else {
11157                    dumpPackage = args[opti];
11158                    opti++;
11159                    newArgs = new String[args.length - opti];
11160                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11161                            args.length - opti);
11162                    args = newArgs;
11163                    opti = 0;
11164                    more = true;
11165                }
11166            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11167                synchronized (this) {
11168                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11169                }
11170            } else {
11171                // Dumping a single activity?
11172                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11173                    pw.println("Bad activity command, or no activities match: " + cmd);
11174                    pw.println("Use -h for help.");
11175                }
11176            }
11177            if (!more) {
11178                Binder.restoreCallingIdentity(origId);
11179                return;
11180            }
11181        }
11182
11183        // No piece of data specified, dump everything.
11184        synchronized (this) {
11185            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11186            pw.println();
11187            if (dumpAll) {
11188                pw.println("-------------------------------------------------------------------------------");
11189            }
11190            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11191            pw.println();
11192            if (dumpAll) {
11193                pw.println("-------------------------------------------------------------------------------");
11194            }
11195            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11196            pw.println();
11197            if (dumpAll) {
11198                pw.println("-------------------------------------------------------------------------------");
11199            }
11200            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11201            pw.println();
11202            if (dumpAll) {
11203                pw.println("-------------------------------------------------------------------------------");
11204            }
11205            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11206            pw.println();
11207            if (dumpAll) {
11208                pw.println("-------------------------------------------------------------------------------");
11209            }
11210            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11211        }
11212        Binder.restoreCallingIdentity(origId);
11213    }
11214
11215    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11216            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11217        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11218
11219        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11220                dumpPackage);
11221        boolean needSep = printedAnything;
11222
11223        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11224                dumpPackage, needSep, "  mFocusedActivity: ");
11225        if (printed) {
11226            printedAnything = true;
11227            needSep = false;
11228        }
11229
11230        if (dumpPackage == null) {
11231            if (needSep) {
11232                pw.println();
11233            }
11234            needSep = true;
11235            printedAnything = true;
11236            mStackSupervisor.dump(pw, "  ");
11237        }
11238
11239        if (mRecentTasks.size() > 0) {
11240            boolean printedHeader = false;
11241
11242            final int N = mRecentTasks.size();
11243            for (int i=0; i<N; i++) {
11244                TaskRecord tr = mRecentTasks.get(i);
11245                if (dumpPackage != null) {
11246                    if (tr.realActivity == null ||
11247                            !dumpPackage.equals(tr.realActivity)) {
11248                        continue;
11249                    }
11250                }
11251                if (!printedHeader) {
11252                    if (needSep) {
11253                        pw.println();
11254                    }
11255                    pw.println("  Recent tasks:");
11256                    printedHeader = true;
11257                    printedAnything = true;
11258                }
11259                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11260                        pw.println(tr);
11261                if (dumpAll) {
11262                    mRecentTasks.get(i).dump(pw, "    ");
11263                }
11264            }
11265        }
11266
11267        if (!printedAnything) {
11268            pw.println("  (nothing)");
11269        }
11270    }
11271
11272    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11273            int opti, boolean dumpAll, String dumpPackage) {
11274        boolean needSep = false;
11275        boolean printedAnything = false;
11276        int numPers = 0;
11277
11278        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11279
11280        if (dumpAll) {
11281            final int NP = mProcessNames.getMap().size();
11282            for (int ip=0; ip<NP; ip++) {
11283                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11284                final int NA = procs.size();
11285                for (int ia=0; ia<NA; ia++) {
11286                    ProcessRecord r = procs.valueAt(ia);
11287                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11288                        continue;
11289                    }
11290                    if (!needSep) {
11291                        pw.println("  All known processes:");
11292                        needSep = true;
11293                        printedAnything = true;
11294                    }
11295                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11296                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11297                        pw.print(" "); pw.println(r);
11298                    r.dump(pw, "    ");
11299                    if (r.persistent) {
11300                        numPers++;
11301                    }
11302                }
11303            }
11304        }
11305
11306        if (mIsolatedProcesses.size() > 0) {
11307            boolean printed = false;
11308            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11309                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11310                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11311                    continue;
11312                }
11313                if (!printed) {
11314                    if (needSep) {
11315                        pw.println();
11316                    }
11317                    pw.println("  Isolated process list (sorted by uid):");
11318                    printedAnything = true;
11319                    printed = true;
11320                    needSep = true;
11321                }
11322                pw.println(String.format("%sIsolated #%2d: %s",
11323                        "    ", i, r.toString()));
11324            }
11325        }
11326
11327        if (mLruProcesses.size() > 0) {
11328            if (needSep) {
11329                pw.println();
11330            }
11331            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11332                    pw.print(" total, non-act at ");
11333                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11334                    pw.print(", non-svc at ");
11335                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11336                    pw.println("):");
11337            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11338            needSep = true;
11339            printedAnything = true;
11340        }
11341
11342        if (dumpAll || dumpPackage != null) {
11343            synchronized (mPidsSelfLocked) {
11344                boolean printed = false;
11345                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11346                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11347                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11348                        continue;
11349                    }
11350                    if (!printed) {
11351                        if (needSep) pw.println();
11352                        needSep = true;
11353                        pw.println("  PID mappings:");
11354                        printed = true;
11355                        printedAnything = true;
11356                    }
11357                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11358                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11359                }
11360            }
11361        }
11362
11363        if (mForegroundProcesses.size() > 0) {
11364            synchronized (mPidsSelfLocked) {
11365                boolean printed = false;
11366                for (int i=0; i<mForegroundProcesses.size(); i++) {
11367                    ProcessRecord r = mPidsSelfLocked.get(
11368                            mForegroundProcesses.valueAt(i).pid);
11369                    if (dumpPackage != null && (r == null
11370                            || !r.pkgList.containsKey(dumpPackage))) {
11371                        continue;
11372                    }
11373                    if (!printed) {
11374                        if (needSep) pw.println();
11375                        needSep = true;
11376                        pw.println("  Foreground Processes:");
11377                        printed = true;
11378                        printedAnything = true;
11379                    }
11380                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11381                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11382                }
11383            }
11384        }
11385
11386        if (mPersistentStartingProcesses.size() > 0) {
11387            if (needSep) pw.println();
11388            needSep = true;
11389            printedAnything = true;
11390            pw.println("  Persisent processes that are starting:");
11391            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11392                    "Starting Norm", "Restarting PERS", dumpPackage);
11393        }
11394
11395        if (mRemovedProcesses.size() > 0) {
11396            if (needSep) pw.println();
11397            needSep = true;
11398            printedAnything = true;
11399            pw.println("  Processes that are being removed:");
11400            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11401                    "Removed Norm", "Removed PERS", dumpPackage);
11402        }
11403
11404        if (mProcessesOnHold.size() > 0) {
11405            if (needSep) pw.println();
11406            needSep = true;
11407            printedAnything = true;
11408            pw.println("  Processes that are on old until the system is ready:");
11409            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11410                    "OnHold Norm", "OnHold PERS", dumpPackage);
11411        }
11412
11413        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11414
11415        if (mProcessCrashTimes.getMap().size() > 0) {
11416            boolean printed = false;
11417            long now = SystemClock.uptimeMillis();
11418            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11419            final int NP = pmap.size();
11420            for (int ip=0; ip<NP; ip++) {
11421                String pname = pmap.keyAt(ip);
11422                SparseArray<Long> uids = pmap.valueAt(ip);
11423                final int N = uids.size();
11424                for (int i=0; i<N; i++) {
11425                    int puid = uids.keyAt(i);
11426                    ProcessRecord r = mProcessNames.get(pname, puid);
11427                    if (dumpPackage != null && (r == null
11428                            || !r.pkgList.containsKey(dumpPackage))) {
11429                        continue;
11430                    }
11431                    if (!printed) {
11432                        if (needSep) pw.println();
11433                        needSep = true;
11434                        pw.println("  Time since processes crashed:");
11435                        printed = true;
11436                        printedAnything = true;
11437                    }
11438                    pw.print("    Process "); pw.print(pname);
11439                            pw.print(" uid "); pw.print(puid);
11440                            pw.print(": last crashed ");
11441                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11442                            pw.println(" ago");
11443                }
11444            }
11445        }
11446
11447        if (mBadProcesses.getMap().size() > 0) {
11448            boolean printed = false;
11449            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11450            final int NP = pmap.size();
11451            for (int ip=0; ip<NP; ip++) {
11452                String pname = pmap.keyAt(ip);
11453                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11454                final int N = uids.size();
11455                for (int i=0; i<N; i++) {
11456                    int puid = uids.keyAt(i);
11457                    ProcessRecord r = mProcessNames.get(pname, puid);
11458                    if (dumpPackage != null && (r == null
11459                            || !r.pkgList.containsKey(dumpPackage))) {
11460                        continue;
11461                    }
11462                    if (!printed) {
11463                        if (needSep) pw.println();
11464                        needSep = true;
11465                        pw.println("  Bad processes:");
11466                        printedAnything = true;
11467                    }
11468                    BadProcessInfo info = uids.valueAt(i);
11469                    pw.print("    Bad process "); pw.print(pname);
11470                            pw.print(" uid "); pw.print(puid);
11471                            pw.print(": crashed at time "); pw.println(info.time);
11472                    if (info.shortMsg != null) {
11473                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11474                    }
11475                    if (info.longMsg != null) {
11476                        pw.print("      Long msg: "); pw.println(info.longMsg);
11477                    }
11478                    if (info.stack != null) {
11479                        pw.println("      Stack:");
11480                        int lastPos = 0;
11481                        for (int pos=0; pos<info.stack.length(); pos++) {
11482                            if (info.stack.charAt(pos) == '\n') {
11483                                pw.print("        ");
11484                                pw.write(info.stack, lastPos, pos-lastPos);
11485                                pw.println();
11486                                lastPos = pos+1;
11487                            }
11488                        }
11489                        if (lastPos < info.stack.length()) {
11490                            pw.print("        ");
11491                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11492                            pw.println();
11493                        }
11494                    }
11495                }
11496            }
11497        }
11498
11499        if (dumpPackage == null) {
11500            pw.println();
11501            needSep = false;
11502            pw.println("  mStartedUsers:");
11503            for (int i=0; i<mStartedUsers.size(); i++) {
11504                UserStartedState uss = mStartedUsers.valueAt(i);
11505                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11506                        pw.print(": "); uss.dump("", pw);
11507            }
11508            pw.print("  mStartedUserArray: [");
11509            for (int i=0; i<mStartedUserArray.length; i++) {
11510                if (i > 0) pw.print(", ");
11511                pw.print(mStartedUserArray[i]);
11512            }
11513            pw.println("]");
11514            pw.print("  mUserLru: [");
11515            for (int i=0; i<mUserLru.size(); i++) {
11516                if (i > 0) pw.print(", ");
11517                pw.print(mUserLru.get(i));
11518            }
11519            pw.println("]");
11520            if (dumpAll) {
11521                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11522            }
11523        }
11524        if (mHomeProcess != null && (dumpPackage == null
11525                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11526            if (needSep) {
11527                pw.println();
11528                needSep = false;
11529            }
11530            pw.println("  mHomeProcess: " + mHomeProcess);
11531        }
11532        if (mPreviousProcess != null && (dumpPackage == null
11533                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11534            if (needSep) {
11535                pw.println();
11536                needSep = false;
11537            }
11538            pw.println("  mPreviousProcess: " + mPreviousProcess);
11539        }
11540        if (dumpAll) {
11541            StringBuilder sb = new StringBuilder(128);
11542            sb.append("  mPreviousProcessVisibleTime: ");
11543            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11544            pw.println(sb);
11545        }
11546        if (mHeavyWeightProcess != null && (dumpPackage == null
11547                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11548            if (needSep) {
11549                pw.println();
11550                needSep = false;
11551            }
11552            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11553        }
11554        if (dumpPackage == null) {
11555            pw.println("  mConfiguration: " + mConfiguration);
11556        }
11557        if (dumpAll) {
11558            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11559            if (mCompatModePackages.getPackages().size() > 0) {
11560                boolean printed = false;
11561                for (Map.Entry<String, Integer> entry
11562                        : mCompatModePackages.getPackages().entrySet()) {
11563                    String pkg = entry.getKey();
11564                    int mode = entry.getValue();
11565                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11566                        continue;
11567                    }
11568                    if (!printed) {
11569                        pw.println("  mScreenCompatPackages:");
11570                        printed = true;
11571                    }
11572                    pw.print("    "); pw.print(pkg); pw.print(": ");
11573                            pw.print(mode); pw.println();
11574                }
11575            }
11576        }
11577        if (dumpPackage == null) {
11578            if (mSleeping || mWentToSleep || mLockScreenShown) {
11579                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11580                        + " mLockScreenShown " + mLockScreenShown);
11581            }
11582            if (mShuttingDown || mRunningVoice) {
11583                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11584            }
11585        }
11586        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11587                || mOrigWaitForDebugger) {
11588            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11589                    || dumpPackage.equals(mOrigDebugApp)) {
11590                if (needSep) {
11591                    pw.println();
11592                    needSep = false;
11593                }
11594                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11595                        + " mDebugTransient=" + mDebugTransient
11596                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11597            }
11598        }
11599        if (mOpenGlTraceApp != null) {
11600            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11601                if (needSep) {
11602                    pw.println();
11603                    needSep = false;
11604                }
11605                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11606            }
11607        }
11608        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11609                || mProfileFd != null) {
11610            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11611                if (needSep) {
11612                    pw.println();
11613                    needSep = false;
11614                }
11615                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11616                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11617                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11618                        + mAutoStopProfiler);
11619            }
11620        }
11621        if (dumpPackage == null) {
11622            if (mAlwaysFinishActivities || mController != null) {
11623                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11624                        + " mController=" + mController);
11625            }
11626            if (dumpAll) {
11627                pw.println("  Total persistent processes: " + numPers);
11628                pw.println("  mProcessesReady=" + mProcessesReady
11629                        + " mSystemReady=" + mSystemReady);
11630                pw.println("  mBooting=" + mBooting
11631                        + " mBooted=" + mBooted
11632                        + " mFactoryTest=" + mFactoryTest);
11633                pw.print("  mLastPowerCheckRealtime=");
11634                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11635                        pw.println("");
11636                pw.print("  mLastPowerCheckUptime=");
11637                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11638                        pw.println("");
11639                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11640                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11641                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11642                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11643                        + " (" + mLruProcesses.size() + " total)"
11644                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11645                        + " mNumServiceProcs=" + mNumServiceProcs
11646                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11647                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11648                        + " mLastMemoryLevel" + mLastMemoryLevel
11649                        + " mLastNumProcesses" + mLastNumProcesses);
11650                long now = SystemClock.uptimeMillis();
11651                pw.print("  mLastIdleTime=");
11652                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11653                        pw.print(" mLowRamSinceLastIdle=");
11654                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11655                        pw.println();
11656            }
11657        }
11658
11659        if (!printedAnything) {
11660            pw.println("  (nothing)");
11661        }
11662    }
11663
11664    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11665            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11666        if (mProcessesToGc.size() > 0) {
11667            boolean printed = false;
11668            long now = SystemClock.uptimeMillis();
11669            for (int i=0; i<mProcessesToGc.size(); i++) {
11670                ProcessRecord proc = mProcessesToGc.get(i);
11671                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11672                    continue;
11673                }
11674                if (!printed) {
11675                    if (needSep) pw.println();
11676                    needSep = true;
11677                    pw.println("  Processes that are waiting to GC:");
11678                    printed = true;
11679                }
11680                pw.print("    Process "); pw.println(proc);
11681                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11682                        pw.print(", last gced=");
11683                        pw.print(now-proc.lastRequestedGc);
11684                        pw.print(" ms ago, last lowMem=");
11685                        pw.print(now-proc.lastLowMemory);
11686                        pw.println(" ms ago");
11687
11688            }
11689        }
11690        return needSep;
11691    }
11692
11693    void printOomLevel(PrintWriter pw, String name, int adj) {
11694        pw.print("    ");
11695        if (adj >= 0) {
11696            pw.print(' ');
11697            if (adj < 10) pw.print(' ');
11698        } else {
11699            if (adj > -10) pw.print(' ');
11700        }
11701        pw.print(adj);
11702        pw.print(": ");
11703        pw.print(name);
11704        pw.print(" (");
11705        pw.print(mProcessList.getMemLevel(adj)/1024);
11706        pw.println(" kB)");
11707    }
11708
11709    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11710            int opti, boolean dumpAll) {
11711        boolean needSep = false;
11712
11713        if (mLruProcesses.size() > 0) {
11714            if (needSep) pw.println();
11715            needSep = true;
11716            pw.println("  OOM levels:");
11717            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11718            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11719            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11720            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11721            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11722            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11723            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11724            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11725            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11726            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11727            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11728            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11729            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11730
11731            if (needSep) pw.println();
11732            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11733                    pw.print(" total, non-act at ");
11734                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11735                    pw.print(", non-svc at ");
11736                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11737                    pw.println("):");
11738            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11739            needSep = true;
11740        }
11741
11742        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11743
11744        pw.println();
11745        pw.println("  mHomeProcess: " + mHomeProcess);
11746        pw.println("  mPreviousProcess: " + mPreviousProcess);
11747        if (mHeavyWeightProcess != null) {
11748            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11749        }
11750
11751        return true;
11752    }
11753
11754    /**
11755     * There are three ways to call this:
11756     *  - no provider specified: dump all the providers
11757     *  - a flattened component name that matched an existing provider was specified as the
11758     *    first arg: dump that one provider
11759     *  - the first arg isn't the flattened component name of an existing provider:
11760     *    dump all providers whose component contains the first arg as a substring
11761     */
11762    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11763            int opti, boolean dumpAll) {
11764        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11765    }
11766
11767    static class ItemMatcher {
11768        ArrayList<ComponentName> components;
11769        ArrayList<String> strings;
11770        ArrayList<Integer> objects;
11771        boolean all;
11772
11773        ItemMatcher() {
11774            all = true;
11775        }
11776
11777        void build(String name) {
11778            ComponentName componentName = ComponentName.unflattenFromString(name);
11779            if (componentName != null) {
11780                if (components == null) {
11781                    components = new ArrayList<ComponentName>();
11782                }
11783                components.add(componentName);
11784                all = false;
11785            } else {
11786                int objectId = 0;
11787                // Not a '/' separated full component name; maybe an object ID?
11788                try {
11789                    objectId = Integer.parseInt(name, 16);
11790                    if (objects == null) {
11791                        objects = new ArrayList<Integer>();
11792                    }
11793                    objects.add(objectId);
11794                    all = false;
11795                } catch (RuntimeException e) {
11796                    // Not an integer; just do string match.
11797                    if (strings == null) {
11798                        strings = new ArrayList<String>();
11799                    }
11800                    strings.add(name);
11801                    all = false;
11802                }
11803            }
11804        }
11805
11806        int build(String[] args, int opti) {
11807            for (; opti<args.length; opti++) {
11808                String name = args[opti];
11809                if ("--".equals(name)) {
11810                    return opti+1;
11811                }
11812                build(name);
11813            }
11814            return opti;
11815        }
11816
11817        boolean match(Object object, ComponentName comp) {
11818            if (all) {
11819                return true;
11820            }
11821            if (components != null) {
11822                for (int i=0; i<components.size(); i++) {
11823                    if (components.get(i).equals(comp)) {
11824                        return true;
11825                    }
11826                }
11827            }
11828            if (objects != null) {
11829                for (int i=0; i<objects.size(); i++) {
11830                    if (System.identityHashCode(object) == objects.get(i)) {
11831                        return true;
11832                    }
11833                }
11834            }
11835            if (strings != null) {
11836                String flat = comp.flattenToString();
11837                for (int i=0; i<strings.size(); i++) {
11838                    if (flat.contains(strings.get(i))) {
11839                        return true;
11840                    }
11841                }
11842            }
11843            return false;
11844        }
11845    }
11846
11847    /**
11848     * There are three things that cmd can be:
11849     *  - a flattened component name that matches an existing activity
11850     *  - the cmd arg isn't the flattened component name of an existing activity:
11851     *    dump all activity whose component contains the cmd as a substring
11852     *  - A hex number of the ActivityRecord object instance.
11853     */
11854    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11855            int opti, boolean dumpAll) {
11856        ArrayList<ActivityRecord> activities;
11857
11858        synchronized (this) {
11859            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11860        }
11861
11862        if (activities.size() <= 0) {
11863            return false;
11864        }
11865
11866        String[] newArgs = new String[args.length - opti];
11867        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11868
11869        TaskRecord lastTask = null;
11870        boolean needSep = false;
11871        for (int i=activities.size()-1; i>=0; i--) {
11872            ActivityRecord r = activities.get(i);
11873            if (needSep) {
11874                pw.println();
11875            }
11876            needSep = true;
11877            synchronized (this) {
11878                if (lastTask != r.task) {
11879                    lastTask = r.task;
11880                    pw.print("TASK "); pw.print(lastTask.affinity);
11881                            pw.print(" id="); pw.println(lastTask.taskId);
11882                    if (dumpAll) {
11883                        lastTask.dump(pw, "  ");
11884                    }
11885                }
11886            }
11887            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11888        }
11889        return true;
11890    }
11891
11892    /**
11893     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11894     * there is a thread associated with the activity.
11895     */
11896    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11897            final ActivityRecord r, String[] args, boolean dumpAll) {
11898        String innerPrefix = prefix + "  ";
11899        synchronized (this) {
11900            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11901                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11902                    pw.print(" pid=");
11903                    if (r.app != null) pw.println(r.app.pid);
11904                    else pw.println("(not running)");
11905            if (dumpAll) {
11906                r.dump(pw, innerPrefix);
11907            }
11908        }
11909        if (r.app != null && r.app.thread != null) {
11910            // flush anything that is already in the PrintWriter since the thread is going
11911            // to write to the file descriptor directly
11912            pw.flush();
11913            try {
11914                TransferPipe tp = new TransferPipe();
11915                try {
11916                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11917                            r.appToken, innerPrefix, args);
11918                    tp.go(fd);
11919                } finally {
11920                    tp.kill();
11921                }
11922            } catch (IOException e) {
11923                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11924            } catch (RemoteException e) {
11925                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11926            }
11927        }
11928    }
11929
11930    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11931            int opti, boolean dumpAll, String dumpPackage) {
11932        boolean needSep = false;
11933        boolean onlyHistory = false;
11934        boolean printedAnything = false;
11935
11936        if ("history".equals(dumpPackage)) {
11937            if (opti < args.length && "-s".equals(args[opti])) {
11938                dumpAll = false;
11939            }
11940            onlyHistory = true;
11941            dumpPackage = null;
11942        }
11943
11944        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11945        if (!onlyHistory && dumpAll) {
11946            if (mRegisteredReceivers.size() > 0) {
11947                boolean printed = false;
11948                Iterator it = mRegisteredReceivers.values().iterator();
11949                while (it.hasNext()) {
11950                    ReceiverList r = (ReceiverList)it.next();
11951                    if (dumpPackage != null && (r.app == null ||
11952                            !dumpPackage.equals(r.app.info.packageName))) {
11953                        continue;
11954                    }
11955                    if (!printed) {
11956                        pw.println("  Registered Receivers:");
11957                        needSep = true;
11958                        printed = true;
11959                        printedAnything = true;
11960                    }
11961                    pw.print("  * "); pw.println(r);
11962                    r.dump(pw, "    ");
11963                }
11964            }
11965
11966            if (mReceiverResolver.dump(pw, needSep ?
11967                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11968                    "    ", dumpPackage, false)) {
11969                needSep = true;
11970                printedAnything = true;
11971            }
11972        }
11973
11974        for (BroadcastQueue q : mBroadcastQueues) {
11975            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11976            printedAnything |= needSep;
11977        }
11978
11979        needSep = true;
11980
11981        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11982            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11983                if (needSep) {
11984                    pw.println();
11985                }
11986                needSep = true;
11987                printedAnything = true;
11988                pw.print("  Sticky broadcasts for user ");
11989                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11990                StringBuilder sb = new StringBuilder(128);
11991                for (Map.Entry<String, ArrayList<Intent>> ent
11992                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11993                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11994                    if (dumpAll) {
11995                        pw.println(":");
11996                        ArrayList<Intent> intents = ent.getValue();
11997                        final int N = intents.size();
11998                        for (int i=0; i<N; i++) {
11999                            sb.setLength(0);
12000                            sb.append("    Intent: ");
12001                            intents.get(i).toShortString(sb, false, true, false, false);
12002                            pw.println(sb.toString());
12003                            Bundle bundle = intents.get(i).getExtras();
12004                            if (bundle != null) {
12005                                pw.print("      ");
12006                                pw.println(bundle.toString());
12007                            }
12008                        }
12009                    } else {
12010                        pw.println("");
12011                    }
12012                }
12013            }
12014        }
12015
12016        if (!onlyHistory && dumpAll) {
12017            pw.println();
12018            for (BroadcastQueue queue : mBroadcastQueues) {
12019                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12020                        + queue.mBroadcastsScheduled);
12021            }
12022            pw.println("  mHandler:");
12023            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12024            needSep = true;
12025            printedAnything = true;
12026        }
12027
12028        if (!printedAnything) {
12029            pw.println("  (nothing)");
12030        }
12031    }
12032
12033    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12034            int opti, boolean dumpAll, String dumpPackage) {
12035        boolean needSep;
12036        boolean printedAnything = false;
12037
12038        ItemMatcher matcher = new ItemMatcher();
12039        matcher.build(args, opti);
12040
12041        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12042
12043        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12044        printedAnything |= needSep;
12045
12046        if (mLaunchingProviders.size() > 0) {
12047            boolean printed = false;
12048            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12049                ContentProviderRecord r = mLaunchingProviders.get(i);
12050                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12051                    continue;
12052                }
12053                if (!printed) {
12054                    if (needSep) pw.println();
12055                    needSep = true;
12056                    pw.println("  Launching content providers:");
12057                    printed = true;
12058                    printedAnything = true;
12059                }
12060                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12061                        pw.println(r);
12062            }
12063        }
12064
12065        if (mGrantedUriPermissions.size() > 0) {
12066            boolean printed = false;
12067            int dumpUid = -2;
12068            if (dumpPackage != null) {
12069                try {
12070                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12071                } catch (NameNotFoundException e) {
12072                    dumpUid = -1;
12073                }
12074            }
12075            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12076                int uid = mGrantedUriPermissions.keyAt(i);
12077                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12078                    continue;
12079                }
12080                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12081                if (!printed) {
12082                    if (needSep) pw.println();
12083                    needSep = true;
12084                    pw.println("  Granted Uri Permissions:");
12085                    printed = true;
12086                    printedAnything = true;
12087                }
12088                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12089                for (UriPermission perm : perms.values()) {
12090                    pw.print("    "); pw.println(perm);
12091                    if (dumpAll) {
12092                        perm.dump(pw, "      ");
12093                    }
12094                }
12095            }
12096        }
12097
12098        if (!printedAnything) {
12099            pw.println("  (nothing)");
12100        }
12101    }
12102
12103    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12104            int opti, boolean dumpAll, String dumpPackage) {
12105        boolean printed = false;
12106
12107        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12108
12109        if (mIntentSenderRecords.size() > 0) {
12110            Iterator<WeakReference<PendingIntentRecord>> it
12111                    = mIntentSenderRecords.values().iterator();
12112            while (it.hasNext()) {
12113                WeakReference<PendingIntentRecord> ref = it.next();
12114                PendingIntentRecord rec = ref != null ? ref.get(): null;
12115                if (dumpPackage != null && (rec == null
12116                        || !dumpPackage.equals(rec.key.packageName))) {
12117                    continue;
12118                }
12119                printed = true;
12120                if (rec != null) {
12121                    pw.print("  * "); pw.println(rec);
12122                    if (dumpAll) {
12123                        rec.dump(pw, "    ");
12124                    }
12125                } else {
12126                    pw.print("  * "); pw.println(ref);
12127                }
12128            }
12129        }
12130
12131        if (!printed) {
12132            pw.println("  (nothing)");
12133        }
12134    }
12135
12136    private static final int dumpProcessList(PrintWriter pw,
12137            ActivityManagerService service, List list,
12138            String prefix, String normalLabel, String persistentLabel,
12139            String dumpPackage) {
12140        int numPers = 0;
12141        final int N = list.size()-1;
12142        for (int i=N; i>=0; i--) {
12143            ProcessRecord r = (ProcessRecord)list.get(i);
12144            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12145                continue;
12146            }
12147            pw.println(String.format("%s%s #%2d: %s",
12148                    prefix, (r.persistent ? persistentLabel : normalLabel),
12149                    i, r.toString()));
12150            if (r.persistent) {
12151                numPers++;
12152            }
12153        }
12154        return numPers;
12155    }
12156
12157    private static final boolean dumpProcessOomList(PrintWriter pw,
12158            ActivityManagerService service, List<ProcessRecord> origList,
12159            String prefix, String normalLabel, String persistentLabel,
12160            boolean inclDetails, String dumpPackage) {
12161
12162        ArrayList<Pair<ProcessRecord, Integer>> list
12163                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12164        for (int i=0; i<origList.size(); i++) {
12165            ProcessRecord r = origList.get(i);
12166            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12167                continue;
12168            }
12169            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12170        }
12171
12172        if (list.size() <= 0) {
12173            return false;
12174        }
12175
12176        Comparator<Pair<ProcessRecord, Integer>> comparator
12177                = new Comparator<Pair<ProcessRecord, Integer>>() {
12178            @Override
12179            public int compare(Pair<ProcessRecord, Integer> object1,
12180                    Pair<ProcessRecord, Integer> object2) {
12181                if (object1.first.setAdj != object2.first.setAdj) {
12182                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12183                }
12184                if (object1.second.intValue() != object2.second.intValue()) {
12185                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12186                }
12187                return 0;
12188            }
12189        };
12190
12191        Collections.sort(list, comparator);
12192
12193        final long curRealtime = SystemClock.elapsedRealtime();
12194        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12195        final long curUptime = SystemClock.uptimeMillis();
12196        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12197
12198        for (int i=list.size()-1; i>=0; i--) {
12199            ProcessRecord r = list.get(i).first;
12200            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12201            char schedGroup;
12202            switch (r.setSchedGroup) {
12203                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12204                    schedGroup = 'B';
12205                    break;
12206                case Process.THREAD_GROUP_DEFAULT:
12207                    schedGroup = 'F';
12208                    break;
12209                default:
12210                    schedGroup = '?';
12211                    break;
12212            }
12213            char foreground;
12214            if (r.foregroundActivities) {
12215                foreground = 'A';
12216            } else if (r.foregroundServices) {
12217                foreground = 'S';
12218            } else {
12219                foreground = ' ';
12220            }
12221            String procState = ProcessList.makeProcStateString(r.curProcState);
12222            pw.print(prefix);
12223            pw.print(r.persistent ? persistentLabel : normalLabel);
12224            pw.print(" #");
12225            int num = (origList.size()-1)-list.get(i).second;
12226            if (num < 10) pw.print(' ');
12227            pw.print(num);
12228            pw.print(": ");
12229            pw.print(oomAdj);
12230            pw.print(' ');
12231            pw.print(schedGroup);
12232            pw.print('/');
12233            pw.print(foreground);
12234            pw.print('/');
12235            pw.print(procState);
12236            pw.print(" trm:");
12237            if (r.trimMemoryLevel < 10) pw.print(' ');
12238            pw.print(r.trimMemoryLevel);
12239            pw.print(' ');
12240            pw.print(r.toShortString());
12241            pw.print(" (");
12242            pw.print(r.adjType);
12243            pw.println(')');
12244            if (r.adjSource != null || r.adjTarget != null) {
12245                pw.print(prefix);
12246                pw.print("    ");
12247                if (r.adjTarget instanceof ComponentName) {
12248                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12249                } else if (r.adjTarget != null) {
12250                    pw.print(r.adjTarget.toString());
12251                } else {
12252                    pw.print("{null}");
12253                }
12254                pw.print("<=");
12255                if (r.adjSource instanceof ProcessRecord) {
12256                    pw.print("Proc{");
12257                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12258                    pw.println("}");
12259                } else if (r.adjSource != null) {
12260                    pw.println(r.adjSource.toString());
12261                } else {
12262                    pw.println("{null}");
12263                }
12264            }
12265            if (inclDetails) {
12266                pw.print(prefix);
12267                pw.print("    ");
12268                pw.print("oom: max="); pw.print(r.maxAdj);
12269                pw.print(" curRaw="); pw.print(r.curRawAdj);
12270                pw.print(" setRaw="); pw.print(r.setRawAdj);
12271                pw.print(" cur="); pw.print(r.curAdj);
12272                pw.print(" set="); pw.println(r.setAdj);
12273                pw.print(prefix);
12274                pw.print("    ");
12275                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12276                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12277                pw.print(" lastPss="); pw.print(r.lastPss);
12278                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12279                pw.print(prefix);
12280                pw.print("    ");
12281                pw.print("keeping="); pw.print(r.keeping);
12282                pw.print(" cached="); pw.print(r.cached);
12283                pw.print(" empty="); pw.print(r.empty);
12284                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12285
12286                if (!r.keeping) {
12287                    if (r.lastWakeTime != 0) {
12288                        long wtime;
12289                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12290                        synchronized (stats) {
12291                            wtime = stats.getProcessWakeTime(r.info.uid,
12292                                    r.pid, curRealtime);
12293                        }
12294                        long timeUsed = wtime - r.lastWakeTime;
12295                        pw.print(prefix);
12296                        pw.print("    ");
12297                        pw.print("keep awake over ");
12298                        TimeUtils.formatDuration(realtimeSince, pw);
12299                        pw.print(" used ");
12300                        TimeUtils.formatDuration(timeUsed, pw);
12301                        pw.print(" (");
12302                        pw.print((timeUsed*100)/realtimeSince);
12303                        pw.println("%)");
12304                    }
12305                    if (r.lastCpuTime != 0) {
12306                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12307                        pw.print(prefix);
12308                        pw.print("    ");
12309                        pw.print("run cpu over ");
12310                        TimeUtils.formatDuration(uptimeSince, pw);
12311                        pw.print(" used ");
12312                        TimeUtils.formatDuration(timeUsed, pw);
12313                        pw.print(" (");
12314                        pw.print((timeUsed*100)/uptimeSince);
12315                        pw.println("%)");
12316                    }
12317                }
12318            }
12319        }
12320        return true;
12321    }
12322
12323    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12324        ArrayList<ProcessRecord> procs;
12325        synchronized (this) {
12326            if (args != null && args.length > start
12327                    && args[start].charAt(0) != '-') {
12328                procs = new ArrayList<ProcessRecord>();
12329                int pid = -1;
12330                try {
12331                    pid = Integer.parseInt(args[start]);
12332                } catch (NumberFormatException e) {
12333                }
12334                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12335                    ProcessRecord proc = mLruProcesses.get(i);
12336                    if (proc.pid == pid) {
12337                        procs.add(proc);
12338                    } else if (proc.processName.equals(args[start])) {
12339                        procs.add(proc);
12340                    }
12341                }
12342                if (procs.size() <= 0) {
12343                    return null;
12344                }
12345            } else {
12346                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12347            }
12348        }
12349        return procs;
12350    }
12351
12352    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12353            PrintWriter pw, String[] args) {
12354        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12355        if (procs == null) {
12356            pw.println("No process found for: " + args[0]);
12357            return;
12358        }
12359
12360        long uptime = SystemClock.uptimeMillis();
12361        long realtime = SystemClock.elapsedRealtime();
12362        pw.println("Applications Graphics Acceleration Info:");
12363        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12364
12365        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12366            ProcessRecord r = procs.get(i);
12367            if (r.thread != null) {
12368                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12369                pw.flush();
12370                try {
12371                    TransferPipe tp = new TransferPipe();
12372                    try {
12373                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12374                        tp.go(fd);
12375                    } finally {
12376                        tp.kill();
12377                    }
12378                } catch (IOException e) {
12379                    pw.println("Failure while dumping the app: " + r);
12380                    pw.flush();
12381                } catch (RemoteException e) {
12382                    pw.println("Got a RemoteException while dumping the app " + r);
12383                    pw.flush();
12384                }
12385            }
12386        }
12387    }
12388
12389    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12390        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12391        if (procs == null) {
12392            pw.println("No process found for: " + args[0]);
12393            return;
12394        }
12395
12396        pw.println("Applications Database Info:");
12397
12398        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12399            ProcessRecord r = procs.get(i);
12400            if (r.thread != null) {
12401                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12402                pw.flush();
12403                try {
12404                    TransferPipe tp = new TransferPipe();
12405                    try {
12406                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12407                        tp.go(fd);
12408                    } finally {
12409                        tp.kill();
12410                    }
12411                } catch (IOException e) {
12412                    pw.println("Failure while dumping the app: " + r);
12413                    pw.flush();
12414                } catch (RemoteException e) {
12415                    pw.println("Got a RemoteException while dumping the app " + r);
12416                    pw.flush();
12417                }
12418            }
12419        }
12420    }
12421
12422    final static class MemItem {
12423        final boolean isProc;
12424        final String label;
12425        final String shortLabel;
12426        final long pss;
12427        final int id;
12428        final boolean hasActivities;
12429        ArrayList<MemItem> subitems;
12430
12431        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12432                boolean _hasActivities) {
12433            isProc = true;
12434            label = _label;
12435            shortLabel = _shortLabel;
12436            pss = _pss;
12437            id = _id;
12438            hasActivities = _hasActivities;
12439        }
12440
12441        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12442            isProc = false;
12443            label = _label;
12444            shortLabel = _shortLabel;
12445            pss = _pss;
12446            id = _id;
12447            hasActivities = false;
12448        }
12449    }
12450
12451    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12452            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12453        if (sort && !isCompact) {
12454            Collections.sort(items, new Comparator<MemItem>() {
12455                @Override
12456                public int compare(MemItem lhs, MemItem rhs) {
12457                    if (lhs.pss < rhs.pss) {
12458                        return 1;
12459                    } else if (lhs.pss > rhs.pss) {
12460                        return -1;
12461                    }
12462                    return 0;
12463                }
12464            });
12465        }
12466
12467        for (int i=0; i<items.size(); i++) {
12468            MemItem mi = items.get(i);
12469            if (!isCompact) {
12470                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12471            } else if (mi.isProc) {
12472                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12473                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12474                pw.println(mi.hasActivities ? ",a" : ",e");
12475            } else {
12476                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12477                pw.println(mi.pss);
12478            }
12479            if (mi.subitems != null) {
12480                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12481                        true, isCompact);
12482            }
12483        }
12484    }
12485
12486    // These are in KB.
12487    static final long[] DUMP_MEM_BUCKETS = new long[] {
12488        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12489        120*1024, 160*1024, 200*1024,
12490        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12491        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12492    };
12493
12494    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12495            boolean stackLike) {
12496        int start = label.lastIndexOf('.');
12497        if (start >= 0) start++;
12498        else start = 0;
12499        int end = label.length();
12500        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12501            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12502                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12503                out.append(bucket);
12504                out.append(stackLike ? "MB." : "MB ");
12505                out.append(label, start, end);
12506                return;
12507            }
12508        }
12509        out.append(memKB/1024);
12510        out.append(stackLike ? "MB." : "MB ");
12511        out.append(label, start, end);
12512    }
12513
12514    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12515            ProcessList.NATIVE_ADJ,
12516            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12517            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12518            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12519            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12520            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12521    };
12522    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12523            "Native",
12524            "System", "Persistent", "Foreground",
12525            "Visible", "Perceptible",
12526            "Heavy Weight", "Backup",
12527            "A Services", "Home",
12528            "Previous", "B Services", "Cached"
12529    };
12530    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12531            "native",
12532            "sys", "pers", "fore",
12533            "vis", "percept",
12534            "heavy", "backup",
12535            "servicea", "home",
12536            "prev", "serviceb", "cached"
12537    };
12538
12539    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12540            long realtime, boolean isCheckinRequest, boolean isCompact) {
12541        if (isCheckinRequest || isCompact) {
12542            // short checkin version
12543            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12544        } else {
12545            pw.println("Applications Memory Usage (kB):");
12546            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12547        }
12548    }
12549
12550    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12551            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12552        boolean dumpDetails = false;
12553        boolean dumpFullDetails = false;
12554        boolean dumpDalvik = false;
12555        boolean oomOnly = false;
12556        boolean isCompact = false;
12557        boolean localOnly = false;
12558
12559        int opti = 0;
12560        while (opti < args.length) {
12561            String opt = args[opti];
12562            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12563                break;
12564            }
12565            opti++;
12566            if ("-a".equals(opt)) {
12567                dumpDetails = true;
12568                dumpFullDetails = true;
12569                dumpDalvik = true;
12570            } else if ("-d".equals(opt)) {
12571                dumpDalvik = true;
12572            } else if ("-c".equals(opt)) {
12573                isCompact = true;
12574            } else if ("--oom".equals(opt)) {
12575                oomOnly = true;
12576            } else if ("--local".equals(opt)) {
12577                localOnly = true;
12578            } else if ("-h".equals(opt)) {
12579                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12580                pw.println("  -a: include all available information for each process.");
12581                pw.println("  -d: include dalvik details when dumping process details.");
12582                pw.println("  -c: dump in a compact machine-parseable representation.");
12583                pw.println("  --oom: only show processes organized by oom adj.");
12584                pw.println("  --local: only collect details locally, don't call process.");
12585                pw.println("If [process] is specified it can be the name or ");
12586                pw.println("pid of a specific process to dump.");
12587                return;
12588            } else {
12589                pw.println("Unknown argument: " + opt + "; use -h for help");
12590            }
12591        }
12592
12593        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12594        long uptime = SystemClock.uptimeMillis();
12595        long realtime = SystemClock.elapsedRealtime();
12596        final long[] tmpLong = new long[1];
12597
12598        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12599        if (procs == null) {
12600            // No Java processes.  Maybe they want to print a native process.
12601            if (args != null && args.length > opti
12602                    && args[opti].charAt(0) != '-') {
12603                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12604                        = new ArrayList<ProcessCpuTracker.Stats>();
12605                updateCpuStatsNow();
12606                int findPid = -1;
12607                try {
12608                    findPid = Integer.parseInt(args[opti]);
12609                } catch (NumberFormatException e) {
12610                }
12611                synchronized (mProcessCpuThread) {
12612                    final int N = mProcessCpuTracker.countStats();
12613                    for (int i=0; i<N; i++) {
12614                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12615                        if (st.pid == findPid || (st.baseName != null
12616                                && st.baseName.equals(args[opti]))) {
12617                            nativeProcs.add(st);
12618                        }
12619                    }
12620                }
12621                if (nativeProcs.size() > 0) {
12622                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12623                            isCompact);
12624                    Debug.MemoryInfo mi = null;
12625                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12626                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12627                        final int pid = r.pid;
12628                        if (!isCheckinRequest && dumpDetails) {
12629                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12630                        }
12631                        if (mi == null) {
12632                            mi = new Debug.MemoryInfo();
12633                        }
12634                        if (dumpDetails || (!brief && !oomOnly)) {
12635                            Debug.getMemoryInfo(pid, mi);
12636                        } else {
12637                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12638                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12639                        }
12640                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12641                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12642                        if (isCheckinRequest) {
12643                            pw.println();
12644                        }
12645                    }
12646                    return;
12647                }
12648            }
12649            pw.println("No process found for: " + args[opti]);
12650            return;
12651        }
12652
12653        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12654            dumpDetails = true;
12655        }
12656
12657        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12658
12659        String[] innerArgs = new String[args.length-opti];
12660        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12661
12662        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12663        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12664        long nativePss=0, dalvikPss=0, otherPss=0;
12665        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12666
12667        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12668        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12669                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12670
12671        long totalPss = 0;
12672        long cachedPss = 0;
12673
12674        Debug.MemoryInfo mi = null;
12675        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12676            final ProcessRecord r = procs.get(i);
12677            final IApplicationThread thread;
12678            final int pid;
12679            final int oomAdj;
12680            final boolean hasActivities;
12681            synchronized (this) {
12682                thread = r.thread;
12683                pid = r.pid;
12684                oomAdj = r.getSetAdjWithServices();
12685                hasActivities = r.activities.size() > 0;
12686            }
12687            if (thread != null) {
12688                if (!isCheckinRequest && dumpDetails) {
12689                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12690                }
12691                if (mi == null) {
12692                    mi = new Debug.MemoryInfo();
12693                }
12694                if (dumpDetails || (!brief && !oomOnly)) {
12695                    Debug.getMemoryInfo(pid, mi);
12696                } else {
12697                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12698                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12699                }
12700                if (dumpDetails) {
12701                    if (localOnly) {
12702                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12703                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12704                        if (isCheckinRequest) {
12705                            pw.println();
12706                        }
12707                    } else {
12708                        try {
12709                            pw.flush();
12710                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12711                                    dumpDalvik, innerArgs);
12712                        } catch (RemoteException e) {
12713                            if (!isCheckinRequest) {
12714                                pw.println("Got RemoteException!");
12715                                pw.flush();
12716                            }
12717                        }
12718                    }
12719                }
12720
12721                final long myTotalPss = mi.getTotalPss();
12722                final long myTotalUss = mi.getTotalUss();
12723
12724                synchronized (this) {
12725                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12726                        // Record this for posterity if the process has been stable.
12727                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12728                    }
12729                }
12730
12731                if (!isCheckinRequest && mi != null) {
12732                    totalPss += myTotalPss;
12733                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12734                            (hasActivities ? " / activities)" : ")"),
12735                            r.processName, myTotalPss, pid, hasActivities);
12736                    procMems.add(pssItem);
12737                    procMemsMap.put(pid, pssItem);
12738
12739                    nativePss += mi.nativePss;
12740                    dalvikPss += mi.dalvikPss;
12741                    otherPss += mi.otherPss;
12742                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12743                        long mem = mi.getOtherPss(j);
12744                        miscPss[j] += mem;
12745                        otherPss -= mem;
12746                    }
12747
12748                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12749                        cachedPss += myTotalPss;
12750                    }
12751
12752                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12753                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12754                                || oomIndex == (oomPss.length-1)) {
12755                            oomPss[oomIndex] += myTotalPss;
12756                            if (oomProcs[oomIndex] == null) {
12757                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12758                            }
12759                            oomProcs[oomIndex].add(pssItem);
12760                            break;
12761                        }
12762                    }
12763                }
12764            }
12765        }
12766
12767        long nativeProcTotalPss = 0;
12768
12769        if (!isCheckinRequest && procs.size() > 1) {
12770            // If we are showing aggregations, also look for native processes to
12771            // include so that our aggregations are more accurate.
12772            updateCpuStatsNow();
12773            synchronized (mProcessCpuThread) {
12774                final int N = mProcessCpuTracker.countStats();
12775                for (int i=0; i<N; i++) {
12776                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12777                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12778                        if (mi == null) {
12779                            mi = new Debug.MemoryInfo();
12780                        }
12781                        if (!brief && !oomOnly) {
12782                            Debug.getMemoryInfo(st.pid, mi);
12783                        } else {
12784                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12785                            mi.nativePrivateDirty = (int)tmpLong[0];
12786                        }
12787
12788                        final long myTotalPss = mi.getTotalPss();
12789                        totalPss += myTotalPss;
12790                        nativeProcTotalPss += myTotalPss;
12791
12792                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12793                                st.name, myTotalPss, st.pid, false);
12794                        procMems.add(pssItem);
12795
12796                        nativePss += mi.nativePss;
12797                        dalvikPss += mi.dalvikPss;
12798                        otherPss += mi.otherPss;
12799                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12800                            long mem = mi.getOtherPss(j);
12801                            miscPss[j] += mem;
12802                            otherPss -= mem;
12803                        }
12804                        oomPss[0] += myTotalPss;
12805                        if (oomProcs[0] == null) {
12806                            oomProcs[0] = new ArrayList<MemItem>();
12807                        }
12808                        oomProcs[0].add(pssItem);
12809                    }
12810                }
12811            }
12812
12813            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12814
12815            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12816            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12817            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12818            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12819                String label = Debug.MemoryInfo.getOtherLabel(j);
12820                catMems.add(new MemItem(label, label, miscPss[j], j));
12821            }
12822
12823            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12824            for (int j=0; j<oomPss.length; j++) {
12825                if (oomPss[j] != 0) {
12826                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12827                            : DUMP_MEM_OOM_LABEL[j];
12828                    MemItem item = new MemItem(label, label, oomPss[j],
12829                            DUMP_MEM_OOM_ADJ[j]);
12830                    item.subitems = oomProcs[j];
12831                    oomMems.add(item);
12832                }
12833            }
12834
12835            if (!brief && !oomOnly && !isCompact) {
12836                pw.println();
12837                pw.println("Total PSS by process:");
12838                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12839                pw.println();
12840            }
12841            if (!isCompact) {
12842                pw.println("Total PSS by OOM adjustment:");
12843            }
12844            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12845            if (!brief && !oomOnly) {
12846                PrintWriter out = categoryPw != null ? categoryPw : pw;
12847                if (!isCompact) {
12848                    out.println();
12849                    out.println("Total PSS by category:");
12850                }
12851                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12852            }
12853            if (!isCompact) {
12854                pw.println();
12855            }
12856            MemInfoReader memInfo = new MemInfoReader();
12857            memInfo.readMemInfo();
12858            if (nativeProcTotalPss > 0) {
12859                synchronized (this) {
12860                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12861                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
12862                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12863                            nativeProcTotalPss);
12864                }
12865            }
12866            if (!brief) {
12867                if (!isCompact) {
12868                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12869                    pw.print(" kB (status ");
12870                    switch (mLastMemoryLevel) {
12871                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12872                            pw.println("normal)");
12873                            break;
12874                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12875                            pw.println("moderate)");
12876                            break;
12877                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12878                            pw.println("low)");
12879                            break;
12880                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12881                            pw.println("critical)");
12882                            break;
12883                        default:
12884                            pw.print(mLastMemoryLevel);
12885                            pw.println(")");
12886                            break;
12887                    }
12888                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12889                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12890                            pw.print(cachedPss); pw.print(" cached pss + ");
12891                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12892                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12893                } else {
12894                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12895                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12896                            + memInfo.getFreeSizeKb()); pw.print(",");
12897                    pw.println(totalPss - cachedPss);
12898                }
12899            }
12900            if (!isCompact) {
12901                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12902                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12903                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12904                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12905                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12906                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12907                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12908                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12909                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12910                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12911                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12912            }
12913            if (!brief) {
12914                if (memInfo.getZramTotalSizeKb() != 0) {
12915                    if (!isCompact) {
12916                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12917                                pw.print(" kB physical used for ");
12918                                pw.print(memInfo.getSwapTotalSizeKb()
12919                                        - memInfo.getSwapFreeSizeKb());
12920                                pw.print(" kB in swap (");
12921                                pw.print(memInfo.getSwapTotalSizeKb());
12922                                pw.println(" kB total swap)");
12923                    } else {
12924                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12925                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12926                                pw.println(memInfo.getSwapFreeSizeKb());
12927                    }
12928                }
12929                final int[] SINGLE_LONG_FORMAT = new int[] {
12930                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12931                };
12932                long[] longOut = new long[1];
12933                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12934                        SINGLE_LONG_FORMAT, null, longOut, null);
12935                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12936                longOut[0] = 0;
12937                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12938                        SINGLE_LONG_FORMAT, null, longOut, null);
12939                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12940                longOut[0] = 0;
12941                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12942                        SINGLE_LONG_FORMAT, null, longOut, null);
12943                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12944                longOut[0] = 0;
12945                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12946                        SINGLE_LONG_FORMAT, null, longOut, null);
12947                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12948                if (!isCompact) {
12949                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12950                        pw.print("      KSM: "); pw.print(sharing);
12951                                pw.print(" kB saved from shared ");
12952                                pw.print(shared); pw.println(" kB");
12953                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12954                                pw.print(voltile); pw.println(" kB volatile");
12955                    }
12956                    pw.print("   Tuning: ");
12957                    pw.print(ActivityManager.staticGetMemoryClass());
12958                    pw.print(" (large ");
12959                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12960                    pw.print("), oom ");
12961                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12962                    pw.print(" kB");
12963                    pw.print(", restore limit ");
12964                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12965                    pw.print(" kB");
12966                    if (ActivityManager.isLowRamDeviceStatic()) {
12967                        pw.print(" (low-ram)");
12968                    }
12969                    if (ActivityManager.isHighEndGfx()) {
12970                        pw.print(" (high-end-gfx)");
12971                    }
12972                    pw.println();
12973                } else {
12974                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12975                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12976                    pw.println(voltile);
12977                    pw.print("tuning,");
12978                    pw.print(ActivityManager.staticGetMemoryClass());
12979                    pw.print(',');
12980                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12981                    pw.print(',');
12982                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12983                    if (ActivityManager.isLowRamDeviceStatic()) {
12984                        pw.print(",low-ram");
12985                    }
12986                    if (ActivityManager.isHighEndGfx()) {
12987                        pw.print(",high-end-gfx");
12988                    }
12989                    pw.println();
12990                }
12991            }
12992        }
12993    }
12994
12995    /**
12996     * Searches array of arguments for the specified string
12997     * @param args array of argument strings
12998     * @param value value to search for
12999     * @return true if the value is contained in the array
13000     */
13001    private static boolean scanArgs(String[] args, String value) {
13002        if (args != null) {
13003            for (String arg : args) {
13004                if (value.equals(arg)) {
13005                    return true;
13006                }
13007            }
13008        }
13009        return false;
13010    }
13011
13012    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13013            ContentProviderRecord cpr, boolean always) {
13014        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13015
13016        if (!inLaunching || always) {
13017            synchronized (cpr) {
13018                cpr.launchingApp = null;
13019                cpr.notifyAll();
13020            }
13021            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13022            String names[] = cpr.info.authority.split(";");
13023            for (int j = 0; j < names.length; j++) {
13024                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13025            }
13026        }
13027
13028        for (int i=0; i<cpr.connections.size(); i++) {
13029            ContentProviderConnection conn = cpr.connections.get(i);
13030            if (conn.waiting) {
13031                // If this connection is waiting for the provider, then we don't
13032                // need to mess with its process unless we are always removing
13033                // or for some reason the provider is not currently launching.
13034                if (inLaunching && !always) {
13035                    continue;
13036                }
13037            }
13038            ProcessRecord capp = conn.client;
13039            conn.dead = true;
13040            if (conn.stableCount > 0) {
13041                if (!capp.persistent && capp.thread != null
13042                        && capp.pid != 0
13043                        && capp.pid != MY_PID) {
13044                    killUnneededProcessLocked(capp, "depends on provider "
13045                            + cpr.name.flattenToShortString()
13046                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13047                }
13048            } else if (capp.thread != null && conn.provider.provider != null) {
13049                try {
13050                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13051                } catch (RemoteException e) {
13052                }
13053                // In the protocol here, we don't expect the client to correctly
13054                // clean up this connection, we'll just remove it.
13055                cpr.connections.remove(i);
13056                conn.client.conProviders.remove(conn);
13057            }
13058        }
13059
13060        if (inLaunching && always) {
13061            mLaunchingProviders.remove(cpr);
13062        }
13063        return inLaunching;
13064    }
13065
13066    /**
13067     * Main code for cleaning up a process when it has gone away.  This is
13068     * called both as a result of the process dying, or directly when stopping
13069     * a process when running in single process mode.
13070     */
13071    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13072            boolean restarting, boolean allowRestart, int index) {
13073        if (index >= 0) {
13074            removeLruProcessLocked(app);
13075            ProcessList.remove(app.pid);
13076        }
13077
13078        mProcessesToGc.remove(app);
13079        mPendingPssProcesses.remove(app);
13080
13081        // Dismiss any open dialogs.
13082        if (app.crashDialog != null && !app.forceCrashReport) {
13083            app.crashDialog.dismiss();
13084            app.crashDialog = null;
13085        }
13086        if (app.anrDialog != null) {
13087            app.anrDialog.dismiss();
13088            app.anrDialog = null;
13089        }
13090        if (app.waitDialog != null) {
13091            app.waitDialog.dismiss();
13092            app.waitDialog = null;
13093        }
13094
13095        app.crashing = false;
13096        app.notResponding = false;
13097
13098        app.resetPackageList(mProcessStats);
13099        app.unlinkDeathRecipient();
13100        app.makeInactive(mProcessStats);
13101        app.waitingToKill = null;
13102        app.forcingToForeground = null;
13103        updateProcessForegroundLocked(app, false, false);
13104        app.foregroundActivities = false;
13105        app.hasShownUi = false;
13106        app.treatLikeActivity = false;
13107        app.hasAboveClient = false;
13108        app.hasClientActivities = false;
13109
13110        mServices.killServicesLocked(app, allowRestart);
13111
13112        boolean restart = false;
13113
13114        // Remove published content providers.
13115        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13116            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13117            final boolean always = app.bad || !allowRestart;
13118            if (removeDyingProviderLocked(app, cpr, always) || always) {
13119                // We left the provider in the launching list, need to
13120                // restart it.
13121                restart = true;
13122            }
13123
13124            cpr.provider = null;
13125            cpr.proc = null;
13126        }
13127        app.pubProviders.clear();
13128
13129        // Take care of any launching providers waiting for this process.
13130        if (checkAppInLaunchingProvidersLocked(app, false)) {
13131            restart = true;
13132        }
13133
13134        // Unregister from connected content providers.
13135        if (!app.conProviders.isEmpty()) {
13136            for (int i=0; i<app.conProviders.size(); i++) {
13137                ContentProviderConnection conn = app.conProviders.get(i);
13138                conn.provider.connections.remove(conn);
13139            }
13140            app.conProviders.clear();
13141        }
13142
13143        // At this point there may be remaining entries in mLaunchingProviders
13144        // where we were the only one waiting, so they are no longer of use.
13145        // Look for these and clean up if found.
13146        // XXX Commented out for now.  Trying to figure out a way to reproduce
13147        // the actual situation to identify what is actually going on.
13148        if (false) {
13149            for (int i=0; i<mLaunchingProviders.size(); i++) {
13150                ContentProviderRecord cpr = (ContentProviderRecord)
13151                        mLaunchingProviders.get(i);
13152                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13153                    synchronized (cpr) {
13154                        cpr.launchingApp = null;
13155                        cpr.notifyAll();
13156                    }
13157                }
13158            }
13159        }
13160
13161        skipCurrentReceiverLocked(app);
13162
13163        // Unregister any receivers.
13164        for (int i=app.receivers.size()-1; i>=0; i--) {
13165            removeReceiverLocked(app.receivers.valueAt(i));
13166        }
13167        app.receivers.clear();
13168
13169        // If the app is undergoing backup, tell the backup manager about it
13170        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13171            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13172                    + mBackupTarget.appInfo + " died during backup");
13173            try {
13174                IBackupManager bm = IBackupManager.Stub.asInterface(
13175                        ServiceManager.getService(Context.BACKUP_SERVICE));
13176                bm.agentDisconnected(app.info.packageName);
13177            } catch (RemoteException e) {
13178                // can't happen; backup manager is local
13179            }
13180        }
13181
13182        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13183            ProcessChangeItem item = mPendingProcessChanges.get(i);
13184            if (item.pid == app.pid) {
13185                mPendingProcessChanges.remove(i);
13186                mAvailProcessChanges.add(item);
13187            }
13188        }
13189        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13190
13191        // If the caller is restarting this app, then leave it in its
13192        // current lists and let the caller take care of it.
13193        if (restarting) {
13194            return;
13195        }
13196
13197        if (!app.persistent || app.isolated) {
13198            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13199                    "Removing non-persistent process during cleanup: " + app);
13200            mProcessNames.remove(app.processName, app.uid);
13201            mIsolatedProcesses.remove(app.uid);
13202            if (mHeavyWeightProcess == app) {
13203                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13204                        mHeavyWeightProcess.userId, 0));
13205                mHeavyWeightProcess = null;
13206            }
13207        } else if (!app.removed) {
13208            // This app is persistent, so we need to keep its record around.
13209            // If it is not already on the pending app list, add it there
13210            // and start a new process for it.
13211            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13212                mPersistentStartingProcesses.add(app);
13213                restart = true;
13214            }
13215        }
13216        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13217                "Clean-up removing on hold: " + app);
13218        mProcessesOnHold.remove(app);
13219
13220        if (app == mHomeProcess) {
13221            mHomeProcess = null;
13222        }
13223        if (app == mPreviousProcess) {
13224            mPreviousProcess = null;
13225        }
13226
13227        if (restart && !app.isolated) {
13228            // We have components that still need to be running in the
13229            // process, so re-launch it.
13230            mProcessNames.put(app.processName, app.uid, app);
13231            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13232        } else if (app.pid > 0 && app.pid != MY_PID) {
13233            // Goodbye!
13234            boolean removed;
13235            synchronized (mPidsSelfLocked) {
13236                mPidsSelfLocked.remove(app.pid);
13237                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13238            }
13239            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13240                    app.processName, app.info.uid);
13241            if (app.isolated) {
13242                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13243            }
13244            app.setPid(0);
13245        }
13246    }
13247
13248    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13249        // Look through the content providers we are waiting to have launched,
13250        // and if any run in this process then either schedule a restart of
13251        // the process or kill the client waiting for it if this process has
13252        // gone bad.
13253        int NL = mLaunchingProviders.size();
13254        boolean restart = false;
13255        for (int i=0; i<NL; i++) {
13256            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13257            if (cpr.launchingApp == app) {
13258                if (!alwaysBad && !app.bad) {
13259                    restart = true;
13260                } else {
13261                    removeDyingProviderLocked(app, cpr, true);
13262                    // cpr should have been removed from mLaunchingProviders
13263                    NL = mLaunchingProviders.size();
13264                    i--;
13265                }
13266            }
13267        }
13268        return restart;
13269    }
13270
13271    // =========================================================
13272    // SERVICES
13273    // =========================================================
13274
13275    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13276            int flags) {
13277        enforceNotIsolatedCaller("getServices");
13278        synchronized (this) {
13279            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13280        }
13281    }
13282
13283    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13284        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13285        synchronized (this) {
13286            return mServices.getRunningServiceControlPanelLocked(name);
13287        }
13288    }
13289
13290    public ComponentName startService(IApplicationThread caller, Intent service,
13291            String resolvedType, int userId) {
13292        enforceNotIsolatedCaller("startService");
13293        // Refuse possible leaked file descriptors
13294        if (service != null && service.hasFileDescriptors() == true) {
13295            throw new IllegalArgumentException("File descriptors passed in Intent");
13296        }
13297
13298        if (DEBUG_SERVICE)
13299            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13300        synchronized(this) {
13301            final int callingPid = Binder.getCallingPid();
13302            final int callingUid = Binder.getCallingUid();
13303            final long origId = Binder.clearCallingIdentity();
13304            ComponentName res = mServices.startServiceLocked(caller, service,
13305                    resolvedType, callingPid, callingUid, userId);
13306            Binder.restoreCallingIdentity(origId);
13307            return res;
13308        }
13309    }
13310
13311    ComponentName startServiceInPackage(int uid,
13312            Intent service, String resolvedType, int userId) {
13313        synchronized(this) {
13314            if (DEBUG_SERVICE)
13315                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13316            final long origId = Binder.clearCallingIdentity();
13317            ComponentName res = mServices.startServiceLocked(null, service,
13318                    resolvedType, -1, uid, userId);
13319            Binder.restoreCallingIdentity(origId);
13320            return res;
13321        }
13322    }
13323
13324    public int stopService(IApplicationThread caller, Intent service,
13325            String resolvedType, int userId) {
13326        enforceNotIsolatedCaller("stopService");
13327        // Refuse possible leaked file descriptors
13328        if (service != null && service.hasFileDescriptors() == true) {
13329            throw new IllegalArgumentException("File descriptors passed in Intent");
13330        }
13331
13332        synchronized(this) {
13333            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13334        }
13335    }
13336
13337    public IBinder peekService(Intent service, String resolvedType) {
13338        enforceNotIsolatedCaller("peekService");
13339        // Refuse possible leaked file descriptors
13340        if (service != null && service.hasFileDescriptors() == true) {
13341            throw new IllegalArgumentException("File descriptors passed in Intent");
13342        }
13343        synchronized(this) {
13344            return mServices.peekServiceLocked(service, resolvedType);
13345        }
13346    }
13347
13348    public boolean stopServiceToken(ComponentName className, IBinder token,
13349            int startId) {
13350        synchronized(this) {
13351            return mServices.stopServiceTokenLocked(className, token, startId);
13352        }
13353    }
13354
13355    public void setServiceForeground(ComponentName className, IBinder token,
13356            int id, Notification notification, boolean removeNotification) {
13357        synchronized(this) {
13358            mServices.setServiceForegroundLocked(className, token, id, notification,
13359                    removeNotification);
13360        }
13361    }
13362
13363    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13364            boolean requireFull, String name, String callerPackage) {
13365        final int callingUserId = UserHandle.getUserId(callingUid);
13366        if (callingUserId != userId) {
13367            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13368                if ((requireFull || checkComponentPermission(
13369                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13370                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13371                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13372                                callingPid, callingUid, -1, true)
13373                                != PackageManager.PERMISSION_GRANTED) {
13374                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13375                        // In this case, they would like to just execute as their
13376                        // owner user instead of failing.
13377                        userId = callingUserId;
13378                    } else {
13379                        StringBuilder builder = new StringBuilder(128);
13380                        builder.append("Permission Denial: ");
13381                        builder.append(name);
13382                        if (callerPackage != null) {
13383                            builder.append(" from ");
13384                            builder.append(callerPackage);
13385                        }
13386                        builder.append(" asks to run as user ");
13387                        builder.append(userId);
13388                        builder.append(" but is calling from user ");
13389                        builder.append(UserHandle.getUserId(callingUid));
13390                        builder.append("; this requires ");
13391                        builder.append(INTERACT_ACROSS_USERS_FULL);
13392                        if (!requireFull) {
13393                            builder.append(" or ");
13394                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13395                        }
13396                        String msg = builder.toString();
13397                        Slog.w(TAG, msg);
13398                        throw new SecurityException(msg);
13399                    }
13400                }
13401            }
13402            if (userId == UserHandle.USER_CURRENT
13403                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13404                // Note that we may be accessing this outside of a lock...
13405                // shouldn't be a big deal, if this is being called outside
13406                // of a locked context there is intrinsically a race with
13407                // the value the caller will receive and someone else changing it.
13408                userId = mCurrentUserId;
13409            }
13410            if (!allowAll && userId < 0) {
13411                throw new IllegalArgumentException(
13412                        "Call does not support special user #" + userId);
13413            }
13414        }
13415        return userId;
13416    }
13417
13418    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13419            String className, int flags) {
13420        boolean result = false;
13421        // For apps that don't have pre-defined UIDs, check for permission
13422        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13423            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13424                if (ActivityManager.checkUidPermission(
13425                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13426                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13427                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13428                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13429                            + " requests FLAG_SINGLE_USER, but app does not hold "
13430                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13431                    Slog.w(TAG, msg);
13432                    throw new SecurityException(msg);
13433                }
13434                // Permission passed
13435                result = true;
13436            }
13437        } else if ("system".equals(componentProcessName)) {
13438            result = true;
13439        } else {
13440            // App with pre-defined UID, check if it's a persistent app
13441            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13442        }
13443        if (DEBUG_MU) {
13444            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13445                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13446        }
13447        return result;
13448    }
13449
13450    /**
13451     * Checks to see if the caller is in the same app as the singleton
13452     * component, or the component is in a special app. It allows special apps
13453     * to export singleton components but prevents exporting singleton
13454     * components for regular apps.
13455     */
13456    boolean isValidSingletonCall(int callingUid, int componentUid) {
13457        int componentAppId = UserHandle.getAppId(componentUid);
13458        return UserHandle.isSameApp(callingUid, componentUid)
13459                || componentAppId == Process.SYSTEM_UID
13460                || componentAppId == Process.PHONE_UID
13461                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13462                        == PackageManager.PERMISSION_GRANTED;
13463    }
13464
13465    public int bindService(IApplicationThread caller, IBinder token,
13466            Intent service, String resolvedType,
13467            IServiceConnection connection, int flags, int userId) {
13468        enforceNotIsolatedCaller("bindService");
13469        // Refuse possible leaked file descriptors
13470        if (service != null && service.hasFileDescriptors() == true) {
13471            throw new IllegalArgumentException("File descriptors passed in Intent");
13472        }
13473
13474        synchronized(this) {
13475            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13476                    connection, flags, userId);
13477        }
13478    }
13479
13480    public boolean unbindService(IServiceConnection connection) {
13481        synchronized (this) {
13482            return mServices.unbindServiceLocked(connection);
13483        }
13484    }
13485
13486    public void publishService(IBinder token, Intent intent, IBinder service) {
13487        // Refuse possible leaked file descriptors
13488        if (intent != null && intent.hasFileDescriptors() == true) {
13489            throw new IllegalArgumentException("File descriptors passed in Intent");
13490        }
13491
13492        synchronized(this) {
13493            if (!(token instanceof ServiceRecord)) {
13494                throw new IllegalArgumentException("Invalid service token");
13495            }
13496            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13497        }
13498    }
13499
13500    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13501        // Refuse possible leaked file descriptors
13502        if (intent != null && intent.hasFileDescriptors() == true) {
13503            throw new IllegalArgumentException("File descriptors passed in Intent");
13504        }
13505
13506        synchronized(this) {
13507            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13508        }
13509    }
13510
13511    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13512        synchronized(this) {
13513            if (!(token instanceof ServiceRecord)) {
13514                throw new IllegalArgumentException("Invalid service token");
13515            }
13516            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13517        }
13518    }
13519
13520    // =========================================================
13521    // BACKUP AND RESTORE
13522    // =========================================================
13523
13524    // Cause the target app to be launched if necessary and its backup agent
13525    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13526    // activity manager to announce its creation.
13527    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13528        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13529        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13530
13531        synchronized(this) {
13532            // !!! TODO: currently no check here that we're already bound
13533            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13534            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13535            synchronized (stats) {
13536                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13537            }
13538
13539            // Backup agent is now in use, its package can't be stopped.
13540            try {
13541                AppGlobals.getPackageManager().setPackageStoppedState(
13542                        app.packageName, false, UserHandle.getUserId(app.uid));
13543            } catch (RemoteException e) {
13544            } catch (IllegalArgumentException e) {
13545                Slog.w(TAG, "Failed trying to unstop package "
13546                        + app.packageName + ": " + e);
13547            }
13548
13549            BackupRecord r = new BackupRecord(ss, app, backupMode);
13550            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13551                    ? new ComponentName(app.packageName, app.backupAgentName)
13552                    : new ComponentName("android", "FullBackupAgent");
13553            // startProcessLocked() returns existing proc's record if it's already running
13554            ProcessRecord proc = startProcessLocked(app.processName, app,
13555                    false, 0, "backup", hostingName, false, false, false);
13556            if (proc == null) {
13557                Slog.e(TAG, "Unable to start backup agent process " + r);
13558                return false;
13559            }
13560
13561            r.app = proc;
13562            mBackupTarget = r;
13563            mBackupAppName = app.packageName;
13564
13565            // Try not to kill the process during backup
13566            updateOomAdjLocked(proc);
13567
13568            // If the process is already attached, schedule the creation of the backup agent now.
13569            // If it is not yet live, this will be done when it attaches to the framework.
13570            if (proc.thread != null) {
13571                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13572                try {
13573                    proc.thread.scheduleCreateBackupAgent(app,
13574                            compatibilityInfoForPackageLocked(app), backupMode);
13575                } catch (RemoteException e) {
13576                    // Will time out on the backup manager side
13577                }
13578            } else {
13579                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13580            }
13581            // Invariants: at this point, the target app process exists and the application
13582            // is either already running or in the process of coming up.  mBackupTarget and
13583            // mBackupAppName describe the app, so that when it binds back to the AM we
13584            // know that it's scheduled for a backup-agent operation.
13585        }
13586
13587        return true;
13588    }
13589
13590    @Override
13591    public void clearPendingBackup() {
13592        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13593        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13594
13595        synchronized (this) {
13596            mBackupTarget = null;
13597            mBackupAppName = null;
13598        }
13599    }
13600
13601    // A backup agent has just come up
13602    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13603        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13604                + " = " + agent);
13605
13606        synchronized(this) {
13607            if (!agentPackageName.equals(mBackupAppName)) {
13608                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13609                return;
13610            }
13611        }
13612
13613        long oldIdent = Binder.clearCallingIdentity();
13614        try {
13615            IBackupManager bm = IBackupManager.Stub.asInterface(
13616                    ServiceManager.getService(Context.BACKUP_SERVICE));
13617            bm.agentConnected(agentPackageName, agent);
13618        } catch (RemoteException e) {
13619            // can't happen; the backup manager service is local
13620        } catch (Exception e) {
13621            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13622            e.printStackTrace();
13623        } finally {
13624            Binder.restoreCallingIdentity(oldIdent);
13625        }
13626    }
13627
13628    // done with this agent
13629    public void unbindBackupAgent(ApplicationInfo appInfo) {
13630        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13631        if (appInfo == null) {
13632            Slog.w(TAG, "unbind backup agent for null app");
13633            return;
13634        }
13635
13636        synchronized(this) {
13637            try {
13638                if (mBackupAppName == null) {
13639                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13640                    return;
13641                }
13642
13643                if (!mBackupAppName.equals(appInfo.packageName)) {
13644                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13645                    return;
13646                }
13647
13648                // Not backing this app up any more; reset its OOM adjustment
13649                final ProcessRecord proc = mBackupTarget.app;
13650                updateOomAdjLocked(proc);
13651
13652                // If the app crashed during backup, 'thread' will be null here
13653                if (proc.thread != null) {
13654                    try {
13655                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13656                                compatibilityInfoForPackageLocked(appInfo));
13657                    } catch (Exception e) {
13658                        Slog.e(TAG, "Exception when unbinding backup agent:");
13659                        e.printStackTrace();
13660                    }
13661                }
13662            } finally {
13663                mBackupTarget = null;
13664                mBackupAppName = null;
13665            }
13666        }
13667    }
13668    // =========================================================
13669    // BROADCASTS
13670    // =========================================================
13671
13672    private final List getStickiesLocked(String action, IntentFilter filter,
13673            List cur, int userId) {
13674        final ContentResolver resolver = mContext.getContentResolver();
13675        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13676        if (stickies == null) {
13677            return cur;
13678        }
13679        final ArrayList<Intent> list = stickies.get(action);
13680        if (list == null) {
13681            return cur;
13682        }
13683        int N = list.size();
13684        for (int i=0; i<N; i++) {
13685            Intent intent = list.get(i);
13686            if (filter.match(resolver, intent, true, TAG) >= 0) {
13687                if (cur == null) {
13688                    cur = new ArrayList<Intent>();
13689                }
13690                cur.add(intent);
13691            }
13692        }
13693        return cur;
13694    }
13695
13696    boolean isPendingBroadcastProcessLocked(int pid) {
13697        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13698                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13699    }
13700
13701    void skipPendingBroadcastLocked(int pid) {
13702            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13703            for (BroadcastQueue queue : mBroadcastQueues) {
13704                queue.skipPendingBroadcastLocked(pid);
13705            }
13706    }
13707
13708    // The app just attached; send any pending broadcasts that it should receive
13709    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13710        boolean didSomething = false;
13711        for (BroadcastQueue queue : mBroadcastQueues) {
13712            didSomething |= queue.sendPendingBroadcastsLocked(app);
13713        }
13714        return didSomething;
13715    }
13716
13717    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13718            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13719        enforceNotIsolatedCaller("registerReceiver");
13720        int callingUid;
13721        int callingPid;
13722        synchronized(this) {
13723            ProcessRecord callerApp = null;
13724            if (caller != null) {
13725                callerApp = getRecordForAppLocked(caller);
13726                if (callerApp == null) {
13727                    throw new SecurityException(
13728                            "Unable to find app for caller " + caller
13729                            + " (pid=" + Binder.getCallingPid()
13730                            + ") when registering receiver " + receiver);
13731                }
13732                if (callerApp.info.uid != Process.SYSTEM_UID &&
13733                        !callerApp.pkgList.containsKey(callerPackage) &&
13734                        !"android".equals(callerPackage)) {
13735                    throw new SecurityException("Given caller package " + callerPackage
13736                            + " is not running in process " + callerApp);
13737                }
13738                callingUid = callerApp.info.uid;
13739                callingPid = callerApp.pid;
13740            } else {
13741                callerPackage = null;
13742                callingUid = Binder.getCallingUid();
13743                callingPid = Binder.getCallingPid();
13744            }
13745
13746            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13747                    true, true, "registerReceiver", callerPackage);
13748
13749            List allSticky = null;
13750
13751            // Look for any matching sticky broadcasts...
13752            Iterator actions = filter.actionsIterator();
13753            if (actions != null) {
13754                while (actions.hasNext()) {
13755                    String action = (String)actions.next();
13756                    allSticky = getStickiesLocked(action, filter, allSticky,
13757                            UserHandle.USER_ALL);
13758                    allSticky = getStickiesLocked(action, filter, allSticky,
13759                            UserHandle.getUserId(callingUid));
13760                }
13761            } else {
13762                allSticky = getStickiesLocked(null, filter, allSticky,
13763                        UserHandle.USER_ALL);
13764                allSticky = getStickiesLocked(null, filter, allSticky,
13765                        UserHandle.getUserId(callingUid));
13766            }
13767
13768            // The first sticky in the list is returned directly back to
13769            // the client.
13770            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13771
13772            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13773                    + ": " + sticky);
13774
13775            if (receiver == null) {
13776                return sticky;
13777            }
13778
13779            ReceiverList rl
13780                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13781            if (rl == null) {
13782                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13783                        userId, receiver);
13784                if (rl.app != null) {
13785                    rl.app.receivers.add(rl);
13786                } else {
13787                    try {
13788                        receiver.asBinder().linkToDeath(rl, 0);
13789                    } catch (RemoteException e) {
13790                        return sticky;
13791                    }
13792                    rl.linkedToDeath = true;
13793                }
13794                mRegisteredReceivers.put(receiver.asBinder(), rl);
13795            } else if (rl.uid != callingUid) {
13796                throw new IllegalArgumentException(
13797                        "Receiver requested to register for uid " + callingUid
13798                        + " was previously registered for uid " + rl.uid);
13799            } else if (rl.pid != callingPid) {
13800                throw new IllegalArgumentException(
13801                        "Receiver requested to register for pid " + callingPid
13802                        + " was previously registered for pid " + rl.pid);
13803            } else if (rl.userId != userId) {
13804                throw new IllegalArgumentException(
13805                        "Receiver requested to register for user " + userId
13806                        + " was previously registered for user " + rl.userId);
13807            }
13808            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13809                    permission, callingUid, userId);
13810            rl.add(bf);
13811            if (!bf.debugCheck()) {
13812                Slog.w(TAG, "==> For Dynamic broadast");
13813            }
13814            mReceiverResolver.addFilter(bf);
13815
13816            // Enqueue broadcasts for all existing stickies that match
13817            // this filter.
13818            if (allSticky != null) {
13819                ArrayList receivers = new ArrayList();
13820                receivers.add(bf);
13821
13822                int N = allSticky.size();
13823                for (int i=0; i<N; i++) {
13824                    Intent intent = (Intent)allSticky.get(i);
13825                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13826                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13827                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13828                            null, null, false, true, true, -1);
13829                    queue.enqueueParallelBroadcastLocked(r);
13830                    queue.scheduleBroadcastsLocked();
13831                }
13832            }
13833
13834            return sticky;
13835        }
13836    }
13837
13838    public void unregisterReceiver(IIntentReceiver receiver) {
13839        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13840
13841        final long origId = Binder.clearCallingIdentity();
13842        try {
13843            boolean doTrim = false;
13844
13845            synchronized(this) {
13846                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13847                if (rl != null) {
13848                    if (rl.curBroadcast != null) {
13849                        BroadcastRecord r = rl.curBroadcast;
13850                        final boolean doNext = finishReceiverLocked(
13851                                receiver.asBinder(), r.resultCode, r.resultData,
13852                                r.resultExtras, r.resultAbort);
13853                        if (doNext) {
13854                            doTrim = true;
13855                            r.queue.processNextBroadcast(false);
13856                        }
13857                    }
13858
13859                    if (rl.app != null) {
13860                        rl.app.receivers.remove(rl);
13861                    }
13862                    removeReceiverLocked(rl);
13863                    if (rl.linkedToDeath) {
13864                        rl.linkedToDeath = false;
13865                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13866                    }
13867                }
13868            }
13869
13870            // If we actually concluded any broadcasts, we might now be able
13871            // to trim the recipients' apps from our working set
13872            if (doTrim) {
13873                trimApplications();
13874                return;
13875            }
13876
13877        } finally {
13878            Binder.restoreCallingIdentity(origId);
13879        }
13880    }
13881
13882    void removeReceiverLocked(ReceiverList rl) {
13883        mRegisteredReceivers.remove(rl.receiver.asBinder());
13884        int N = rl.size();
13885        for (int i=0; i<N; i++) {
13886            mReceiverResolver.removeFilter(rl.get(i));
13887        }
13888    }
13889
13890    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13891        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13892            ProcessRecord r = mLruProcesses.get(i);
13893            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13894                try {
13895                    r.thread.dispatchPackageBroadcast(cmd, packages);
13896                } catch (RemoteException ex) {
13897                }
13898            }
13899        }
13900    }
13901
13902    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13903            int[] users) {
13904        List<ResolveInfo> receivers = null;
13905        try {
13906            HashSet<ComponentName> singleUserReceivers = null;
13907            boolean scannedFirstReceivers = false;
13908            for (int user : users) {
13909                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13910                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13911                if (user != 0 && newReceivers != null) {
13912                    // If this is not the primary user, we need to check for
13913                    // any receivers that should be filtered out.
13914                    for (int i=0; i<newReceivers.size(); i++) {
13915                        ResolveInfo ri = newReceivers.get(i);
13916                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13917                            newReceivers.remove(i);
13918                            i--;
13919                        }
13920                    }
13921                }
13922                if (newReceivers != null && newReceivers.size() == 0) {
13923                    newReceivers = null;
13924                }
13925                if (receivers == null) {
13926                    receivers = newReceivers;
13927                } else if (newReceivers != null) {
13928                    // We need to concatenate the additional receivers
13929                    // found with what we have do far.  This would be easy,
13930                    // but we also need to de-dup any receivers that are
13931                    // singleUser.
13932                    if (!scannedFirstReceivers) {
13933                        // Collect any single user receivers we had already retrieved.
13934                        scannedFirstReceivers = true;
13935                        for (int i=0; i<receivers.size(); i++) {
13936                            ResolveInfo ri = receivers.get(i);
13937                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13938                                ComponentName cn = new ComponentName(
13939                                        ri.activityInfo.packageName, ri.activityInfo.name);
13940                                if (singleUserReceivers == null) {
13941                                    singleUserReceivers = new HashSet<ComponentName>();
13942                                }
13943                                singleUserReceivers.add(cn);
13944                            }
13945                        }
13946                    }
13947                    // Add the new results to the existing results, tracking
13948                    // and de-dupping single user receivers.
13949                    for (int i=0; i<newReceivers.size(); i++) {
13950                        ResolveInfo ri = newReceivers.get(i);
13951                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13952                            ComponentName cn = new ComponentName(
13953                                    ri.activityInfo.packageName, ri.activityInfo.name);
13954                            if (singleUserReceivers == null) {
13955                                singleUserReceivers = new HashSet<ComponentName>();
13956                            }
13957                            if (!singleUserReceivers.contains(cn)) {
13958                                singleUserReceivers.add(cn);
13959                                receivers.add(ri);
13960                            }
13961                        } else {
13962                            receivers.add(ri);
13963                        }
13964                    }
13965                }
13966            }
13967        } catch (RemoteException ex) {
13968            // pm is in same process, this will never happen.
13969        }
13970        return receivers;
13971    }
13972
13973    private final int broadcastIntentLocked(ProcessRecord callerApp,
13974            String callerPackage, Intent intent, String resolvedType,
13975            IIntentReceiver resultTo, int resultCode, String resultData,
13976            Bundle map, String requiredPermission, int appOp,
13977            boolean ordered, boolean sticky, int callingPid, int callingUid,
13978            int userId) {
13979        intent = new Intent(intent);
13980
13981        // By default broadcasts do not go to stopped apps.
13982        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13983
13984        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13985            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13986            + " ordered=" + ordered + " userid=" + userId);
13987        if ((resultTo != null) && !ordered) {
13988            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13989        }
13990
13991        userId = handleIncomingUser(callingPid, callingUid, userId,
13992                true, false, "broadcast", callerPackage);
13993
13994        // Make sure that the user who is receiving this broadcast is started.
13995        // If not, we will just skip it.
13996
13997
13998        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13999            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14000                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14001                Slog.w(TAG, "Skipping broadcast of " + intent
14002                        + ": user " + userId + " is stopped");
14003                return ActivityManager.BROADCAST_SUCCESS;
14004            }
14005        }
14006
14007        /*
14008         * Prevent non-system code (defined here to be non-persistent
14009         * processes) from sending protected broadcasts.
14010         */
14011        int callingAppId = UserHandle.getAppId(callingUid);
14012        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14013            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14014            || callingAppId == Process.NFC_UID || callingUid == 0) {
14015            // Always okay.
14016        } else if (callerApp == null || !callerApp.persistent) {
14017            try {
14018                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14019                        intent.getAction())) {
14020                    String msg = "Permission Denial: not allowed to send broadcast "
14021                            + intent.getAction() + " from pid="
14022                            + callingPid + ", uid=" + callingUid;
14023                    Slog.w(TAG, msg);
14024                    throw new SecurityException(msg);
14025                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14026                    // Special case for compatibility: we don't want apps to send this,
14027                    // but historically it has not been protected and apps may be using it
14028                    // to poke their own app widget.  So, instead of making it protected,
14029                    // just limit it to the caller.
14030                    if (callerApp == null) {
14031                        String msg = "Permission Denial: not allowed to send broadcast "
14032                                + intent.getAction() + " from unknown caller.";
14033                        Slog.w(TAG, msg);
14034                        throw new SecurityException(msg);
14035                    } else if (intent.getComponent() != null) {
14036                        // They are good enough to send to an explicit component...  verify
14037                        // it is being sent to the calling app.
14038                        if (!intent.getComponent().getPackageName().equals(
14039                                callerApp.info.packageName)) {
14040                            String msg = "Permission Denial: not allowed to send broadcast "
14041                                    + intent.getAction() + " to "
14042                                    + intent.getComponent().getPackageName() + " from "
14043                                    + callerApp.info.packageName;
14044                            Slog.w(TAG, msg);
14045                            throw new SecurityException(msg);
14046                        }
14047                    } else {
14048                        // Limit broadcast to their own package.
14049                        intent.setPackage(callerApp.info.packageName);
14050                    }
14051                }
14052            } catch (RemoteException e) {
14053                Slog.w(TAG, "Remote exception", e);
14054                return ActivityManager.BROADCAST_SUCCESS;
14055            }
14056        }
14057
14058        // Handle special intents: if this broadcast is from the package
14059        // manager about a package being removed, we need to remove all of
14060        // its activities from the history stack.
14061        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14062                intent.getAction());
14063        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14064                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14065                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14066                || uidRemoved) {
14067            if (checkComponentPermission(
14068                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14069                    callingPid, callingUid, -1, true)
14070                    == PackageManager.PERMISSION_GRANTED) {
14071                if (uidRemoved) {
14072                    final Bundle intentExtras = intent.getExtras();
14073                    final int uid = intentExtras != null
14074                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14075                    if (uid >= 0) {
14076                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14077                        synchronized (bs) {
14078                            bs.removeUidStatsLocked(uid);
14079                        }
14080                        mAppOpsService.uidRemoved(uid);
14081                    }
14082                } else {
14083                    // If resources are unavailable just force stop all
14084                    // those packages and flush the attribute cache as well.
14085                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14086                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14087                        if (list != null && (list.length > 0)) {
14088                            for (String pkg : list) {
14089                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14090                                        "storage unmount");
14091                            }
14092                            sendPackageBroadcastLocked(
14093                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14094                        }
14095                    } else {
14096                        Uri data = intent.getData();
14097                        String ssp;
14098                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14099                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14100                                    intent.getAction());
14101                            boolean fullUninstall = removed &&
14102                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14103                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14104                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14105                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14106                                        false, fullUninstall, userId,
14107                                        removed ? "pkg removed" : "pkg changed");
14108                            }
14109                            if (removed) {
14110                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14111                                        new String[] {ssp}, userId);
14112                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14113                                    mAppOpsService.packageRemoved(
14114                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14115
14116                                    // Remove all permissions granted from/to this package
14117                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14118                                }
14119                            }
14120                        }
14121                    }
14122                }
14123            } else {
14124                String msg = "Permission Denial: " + intent.getAction()
14125                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14126                        + ", uid=" + callingUid + ")"
14127                        + " requires "
14128                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14129                Slog.w(TAG, msg);
14130                throw new SecurityException(msg);
14131            }
14132
14133        // Special case for adding a package: by default turn on compatibility
14134        // mode.
14135        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14136            Uri data = intent.getData();
14137            String ssp;
14138            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14139                mCompatModePackages.handlePackageAddedLocked(ssp,
14140                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14141            }
14142        }
14143
14144        /*
14145         * If this is the time zone changed action, queue up a message that will reset the timezone
14146         * of all currently running processes. This message will get queued up before the broadcast
14147         * happens.
14148         */
14149        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14150            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14151        }
14152
14153        /*
14154         * If the user set the time, let all running processes know.
14155         */
14156        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14157            final int is24Hour = intent.getBooleanExtra(
14158                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14159            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14160        }
14161
14162        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14163            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14164        }
14165
14166        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14167            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14168            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14169        }
14170
14171        // Add to the sticky list if requested.
14172        if (sticky) {
14173            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14174                    callingPid, callingUid)
14175                    != PackageManager.PERMISSION_GRANTED) {
14176                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14177                        + callingPid + ", uid=" + callingUid
14178                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14179                Slog.w(TAG, msg);
14180                throw new SecurityException(msg);
14181            }
14182            if (requiredPermission != null) {
14183                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14184                        + " and enforce permission " + requiredPermission);
14185                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14186            }
14187            if (intent.getComponent() != null) {
14188                throw new SecurityException(
14189                        "Sticky broadcasts can't target a specific component");
14190            }
14191            // We use userId directly here, since the "all" target is maintained
14192            // as a separate set of sticky broadcasts.
14193            if (userId != UserHandle.USER_ALL) {
14194                // But first, if this is not a broadcast to all users, then
14195                // make sure it doesn't conflict with an existing broadcast to
14196                // all users.
14197                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14198                        UserHandle.USER_ALL);
14199                if (stickies != null) {
14200                    ArrayList<Intent> list = stickies.get(intent.getAction());
14201                    if (list != null) {
14202                        int N = list.size();
14203                        int i;
14204                        for (i=0; i<N; i++) {
14205                            if (intent.filterEquals(list.get(i))) {
14206                                throw new IllegalArgumentException(
14207                                        "Sticky broadcast " + intent + " for user "
14208                                        + userId + " conflicts with existing global broadcast");
14209                            }
14210                        }
14211                    }
14212                }
14213            }
14214            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14215            if (stickies == null) {
14216                stickies = new ArrayMap<String, ArrayList<Intent>>();
14217                mStickyBroadcasts.put(userId, stickies);
14218            }
14219            ArrayList<Intent> list = stickies.get(intent.getAction());
14220            if (list == null) {
14221                list = new ArrayList<Intent>();
14222                stickies.put(intent.getAction(), list);
14223            }
14224            int N = list.size();
14225            int i;
14226            for (i=0; i<N; i++) {
14227                if (intent.filterEquals(list.get(i))) {
14228                    // This sticky already exists, replace it.
14229                    list.set(i, new Intent(intent));
14230                    break;
14231                }
14232            }
14233            if (i >= N) {
14234                list.add(new Intent(intent));
14235            }
14236        }
14237
14238        int[] users;
14239        if (userId == UserHandle.USER_ALL) {
14240            // Caller wants broadcast to go to all started users.
14241            users = mStartedUserArray;
14242        } else {
14243            // Caller wants broadcast to go to one specific user.
14244            users = new int[] {userId};
14245        }
14246
14247        // Figure out who all will receive this broadcast.
14248        List receivers = null;
14249        List<BroadcastFilter> registeredReceivers = null;
14250        // Need to resolve the intent to interested receivers...
14251        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14252                 == 0) {
14253            receivers = collectReceiverComponents(intent, resolvedType, users);
14254        }
14255        if (intent.getComponent() == null) {
14256            registeredReceivers = mReceiverResolver.queryIntent(intent,
14257                    resolvedType, false, userId);
14258        }
14259
14260        final boolean replacePending =
14261                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14262
14263        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14264                + " replacePending=" + replacePending);
14265
14266        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14267        if (!ordered && NR > 0) {
14268            // If we are not serializing this broadcast, then send the
14269            // registered receivers separately so they don't wait for the
14270            // components to be launched.
14271            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14272            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14273                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14274                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14275                    ordered, sticky, false, userId);
14276            if (DEBUG_BROADCAST) Slog.v(
14277                    TAG, "Enqueueing parallel broadcast " + r);
14278            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14279            if (!replaced) {
14280                queue.enqueueParallelBroadcastLocked(r);
14281                queue.scheduleBroadcastsLocked();
14282            }
14283            registeredReceivers = null;
14284            NR = 0;
14285        }
14286
14287        // Merge into one list.
14288        int ir = 0;
14289        if (receivers != null) {
14290            // A special case for PACKAGE_ADDED: do not allow the package
14291            // being added to see this broadcast.  This prevents them from
14292            // using this as a back door to get run as soon as they are
14293            // installed.  Maybe in the future we want to have a special install
14294            // broadcast or such for apps, but we'd like to deliberately make
14295            // this decision.
14296            String skipPackages[] = null;
14297            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14298                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14299                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14300                Uri data = intent.getData();
14301                if (data != null) {
14302                    String pkgName = data.getSchemeSpecificPart();
14303                    if (pkgName != null) {
14304                        skipPackages = new String[] { pkgName };
14305                    }
14306                }
14307            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14308                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14309            }
14310            if (skipPackages != null && (skipPackages.length > 0)) {
14311                for (String skipPackage : skipPackages) {
14312                    if (skipPackage != null) {
14313                        int NT = receivers.size();
14314                        for (int it=0; it<NT; it++) {
14315                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14316                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14317                                receivers.remove(it);
14318                                it--;
14319                                NT--;
14320                            }
14321                        }
14322                    }
14323                }
14324            }
14325
14326            int NT = receivers != null ? receivers.size() : 0;
14327            int it = 0;
14328            ResolveInfo curt = null;
14329            BroadcastFilter curr = null;
14330            while (it < NT && ir < NR) {
14331                if (curt == null) {
14332                    curt = (ResolveInfo)receivers.get(it);
14333                }
14334                if (curr == null) {
14335                    curr = registeredReceivers.get(ir);
14336                }
14337                if (curr.getPriority() >= curt.priority) {
14338                    // Insert this broadcast record into the final list.
14339                    receivers.add(it, curr);
14340                    ir++;
14341                    curr = null;
14342                    it++;
14343                    NT++;
14344                } else {
14345                    // Skip to the next ResolveInfo in the final list.
14346                    it++;
14347                    curt = null;
14348                }
14349            }
14350        }
14351        while (ir < NR) {
14352            if (receivers == null) {
14353                receivers = new ArrayList();
14354            }
14355            receivers.add(registeredReceivers.get(ir));
14356            ir++;
14357        }
14358
14359        if ((receivers != null && receivers.size() > 0)
14360                || resultTo != null) {
14361            BroadcastQueue queue = broadcastQueueForIntent(intent);
14362            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14363                    callerPackage, callingPid, callingUid, resolvedType,
14364                    requiredPermission, appOp, receivers, resultTo, resultCode,
14365                    resultData, map, ordered, sticky, false, userId);
14366            if (DEBUG_BROADCAST) Slog.v(
14367                    TAG, "Enqueueing ordered broadcast " + r
14368                    + ": prev had " + queue.mOrderedBroadcasts.size());
14369            if (DEBUG_BROADCAST) {
14370                int seq = r.intent.getIntExtra("seq", -1);
14371                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14372            }
14373            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14374            if (!replaced) {
14375                queue.enqueueOrderedBroadcastLocked(r);
14376                queue.scheduleBroadcastsLocked();
14377            }
14378        }
14379
14380        return ActivityManager.BROADCAST_SUCCESS;
14381    }
14382
14383    final Intent verifyBroadcastLocked(Intent intent) {
14384        // Refuse possible leaked file descriptors
14385        if (intent != null && intent.hasFileDescriptors() == true) {
14386            throw new IllegalArgumentException("File descriptors passed in Intent");
14387        }
14388
14389        int flags = intent.getFlags();
14390
14391        if (!mProcessesReady) {
14392            // if the caller really truly claims to know what they're doing, go
14393            // ahead and allow the broadcast without launching any receivers
14394            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14395                intent = new Intent(intent);
14396                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14397            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14398                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14399                        + " before boot completion");
14400                throw new IllegalStateException("Cannot broadcast before boot completed");
14401            }
14402        }
14403
14404        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14405            throw new IllegalArgumentException(
14406                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14407        }
14408
14409        return intent;
14410    }
14411
14412    public final int broadcastIntent(IApplicationThread caller,
14413            Intent intent, String resolvedType, IIntentReceiver resultTo,
14414            int resultCode, String resultData, Bundle map,
14415            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14416        enforceNotIsolatedCaller("broadcastIntent");
14417        synchronized(this) {
14418            intent = verifyBroadcastLocked(intent);
14419
14420            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14421            final int callingPid = Binder.getCallingPid();
14422            final int callingUid = Binder.getCallingUid();
14423            final long origId = Binder.clearCallingIdentity();
14424            int res = broadcastIntentLocked(callerApp,
14425                    callerApp != null ? callerApp.info.packageName : null,
14426                    intent, resolvedType, resultTo,
14427                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14428                    callingPid, callingUid, userId);
14429            Binder.restoreCallingIdentity(origId);
14430            return res;
14431        }
14432    }
14433
14434    int broadcastIntentInPackage(String packageName, int uid,
14435            Intent intent, String resolvedType, IIntentReceiver resultTo,
14436            int resultCode, String resultData, Bundle map,
14437            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14438        synchronized(this) {
14439            intent = verifyBroadcastLocked(intent);
14440
14441            final long origId = Binder.clearCallingIdentity();
14442            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14443                    resultTo, resultCode, resultData, map, requiredPermission,
14444                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14445            Binder.restoreCallingIdentity(origId);
14446            return res;
14447        }
14448    }
14449
14450    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14451        // Refuse possible leaked file descriptors
14452        if (intent != null && intent.hasFileDescriptors() == true) {
14453            throw new IllegalArgumentException("File descriptors passed in Intent");
14454        }
14455
14456        userId = handleIncomingUser(Binder.getCallingPid(),
14457                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14458
14459        synchronized(this) {
14460            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14461                    != PackageManager.PERMISSION_GRANTED) {
14462                String msg = "Permission Denial: unbroadcastIntent() from pid="
14463                        + Binder.getCallingPid()
14464                        + ", uid=" + Binder.getCallingUid()
14465                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14466                Slog.w(TAG, msg);
14467                throw new SecurityException(msg);
14468            }
14469            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14470            if (stickies != null) {
14471                ArrayList<Intent> list = stickies.get(intent.getAction());
14472                if (list != null) {
14473                    int N = list.size();
14474                    int i;
14475                    for (i=0; i<N; i++) {
14476                        if (intent.filterEquals(list.get(i))) {
14477                            list.remove(i);
14478                            break;
14479                        }
14480                    }
14481                    if (list.size() <= 0) {
14482                        stickies.remove(intent.getAction());
14483                    }
14484                }
14485                if (stickies.size() <= 0) {
14486                    mStickyBroadcasts.remove(userId);
14487                }
14488            }
14489        }
14490    }
14491
14492    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14493            String resultData, Bundle resultExtras, boolean resultAbort) {
14494        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14495        if (r == null) {
14496            Slog.w(TAG, "finishReceiver called but not found on queue");
14497            return false;
14498        }
14499
14500        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14501    }
14502
14503    void backgroundServicesFinishedLocked(int userId) {
14504        for (BroadcastQueue queue : mBroadcastQueues) {
14505            queue.backgroundServicesFinishedLocked(userId);
14506        }
14507    }
14508
14509    public void finishReceiver(IBinder who, int resultCode, String resultData,
14510            Bundle resultExtras, boolean resultAbort) {
14511        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14512
14513        // Refuse possible leaked file descriptors
14514        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14515            throw new IllegalArgumentException("File descriptors passed in Bundle");
14516        }
14517
14518        final long origId = Binder.clearCallingIdentity();
14519        try {
14520            boolean doNext = false;
14521            BroadcastRecord r;
14522
14523            synchronized(this) {
14524                r = broadcastRecordForReceiverLocked(who);
14525                if (r != null) {
14526                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14527                        resultData, resultExtras, resultAbort, true);
14528                }
14529            }
14530
14531            if (doNext) {
14532                r.queue.processNextBroadcast(false);
14533            }
14534            trimApplications();
14535        } finally {
14536            Binder.restoreCallingIdentity(origId);
14537        }
14538    }
14539
14540    // =========================================================
14541    // INSTRUMENTATION
14542    // =========================================================
14543
14544    public boolean startInstrumentation(ComponentName className,
14545            String profileFile, int flags, Bundle arguments,
14546            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14547            int userId, String abiOverride) {
14548        enforceNotIsolatedCaller("startInstrumentation");
14549        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14550                userId, false, true, "startInstrumentation", null);
14551        // Refuse possible leaked file descriptors
14552        if (arguments != null && arguments.hasFileDescriptors()) {
14553            throw new IllegalArgumentException("File descriptors passed in Bundle");
14554        }
14555
14556        synchronized(this) {
14557            InstrumentationInfo ii = null;
14558            ApplicationInfo ai = null;
14559            try {
14560                ii = mContext.getPackageManager().getInstrumentationInfo(
14561                    className, STOCK_PM_FLAGS);
14562                ai = AppGlobals.getPackageManager().getApplicationInfo(
14563                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14564            } catch (PackageManager.NameNotFoundException e) {
14565            } catch (RemoteException e) {
14566            }
14567            if (ii == null) {
14568                reportStartInstrumentationFailure(watcher, className,
14569                        "Unable to find instrumentation info for: " + className);
14570                return false;
14571            }
14572            if (ai == null) {
14573                reportStartInstrumentationFailure(watcher, className,
14574                        "Unable to find instrumentation target package: " + ii.targetPackage);
14575                return false;
14576            }
14577
14578            int match = mContext.getPackageManager().checkSignatures(
14579                    ii.targetPackage, ii.packageName);
14580            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14581                String msg = "Permission Denial: starting instrumentation "
14582                        + className + " from pid="
14583                        + Binder.getCallingPid()
14584                        + ", uid=" + Binder.getCallingPid()
14585                        + " not allowed because package " + ii.packageName
14586                        + " does not have a signature matching the target "
14587                        + ii.targetPackage;
14588                reportStartInstrumentationFailure(watcher, className, msg);
14589                throw new SecurityException(msg);
14590            }
14591
14592            final long origId = Binder.clearCallingIdentity();
14593            // Instrumentation can kill and relaunch even persistent processes
14594            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14595                    "start instr");
14596            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14597            app.instrumentationClass = className;
14598            app.instrumentationInfo = ai;
14599            app.instrumentationProfileFile = profileFile;
14600            app.instrumentationArguments = arguments;
14601            app.instrumentationWatcher = watcher;
14602            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14603            app.instrumentationResultClass = className;
14604            Binder.restoreCallingIdentity(origId);
14605        }
14606
14607        return true;
14608    }
14609
14610    /**
14611     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14612     * error to the logs, but if somebody is watching, send the report there too.  This enables
14613     * the "am" command to report errors with more information.
14614     *
14615     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14616     * @param cn The component name of the instrumentation.
14617     * @param report The error report.
14618     */
14619    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14620            ComponentName cn, String report) {
14621        Slog.w(TAG, report);
14622        try {
14623            if (watcher != null) {
14624                Bundle results = new Bundle();
14625                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14626                results.putString("Error", report);
14627                watcher.instrumentationStatus(cn, -1, results);
14628            }
14629        } catch (RemoteException e) {
14630            Slog.w(TAG, e);
14631        }
14632    }
14633
14634    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14635        if (app.instrumentationWatcher != null) {
14636            try {
14637                // NOTE:  IInstrumentationWatcher *must* be oneway here
14638                app.instrumentationWatcher.instrumentationFinished(
14639                    app.instrumentationClass,
14640                    resultCode,
14641                    results);
14642            } catch (RemoteException e) {
14643            }
14644        }
14645        if (app.instrumentationUiAutomationConnection != null) {
14646            try {
14647                app.instrumentationUiAutomationConnection.shutdown();
14648            } catch (RemoteException re) {
14649                /* ignore */
14650            }
14651            // Only a UiAutomation can set this flag and now that
14652            // it is finished we make sure it is reset to its default.
14653            mUserIsMonkey = false;
14654        }
14655        app.instrumentationWatcher = null;
14656        app.instrumentationUiAutomationConnection = null;
14657        app.instrumentationClass = null;
14658        app.instrumentationInfo = null;
14659        app.instrumentationProfileFile = null;
14660        app.instrumentationArguments = null;
14661
14662        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14663                "finished inst");
14664    }
14665
14666    public void finishInstrumentation(IApplicationThread target,
14667            int resultCode, Bundle results) {
14668        int userId = UserHandle.getCallingUserId();
14669        // Refuse possible leaked file descriptors
14670        if (results != null && results.hasFileDescriptors()) {
14671            throw new IllegalArgumentException("File descriptors passed in Intent");
14672        }
14673
14674        synchronized(this) {
14675            ProcessRecord app = getRecordForAppLocked(target);
14676            if (app == null) {
14677                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14678                return;
14679            }
14680            final long origId = Binder.clearCallingIdentity();
14681            finishInstrumentationLocked(app, resultCode, results);
14682            Binder.restoreCallingIdentity(origId);
14683        }
14684    }
14685
14686    // =========================================================
14687    // CONFIGURATION
14688    // =========================================================
14689
14690    public ConfigurationInfo getDeviceConfigurationInfo() {
14691        ConfigurationInfo config = new ConfigurationInfo();
14692        synchronized (this) {
14693            config.reqTouchScreen = mConfiguration.touchscreen;
14694            config.reqKeyboardType = mConfiguration.keyboard;
14695            config.reqNavigation = mConfiguration.navigation;
14696            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14697                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14698                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14699            }
14700            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14701                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14702                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14703            }
14704            config.reqGlEsVersion = GL_ES_VERSION;
14705        }
14706        return config;
14707    }
14708
14709    ActivityStack getFocusedStack() {
14710        return mStackSupervisor.getFocusedStack();
14711    }
14712
14713    public Configuration getConfiguration() {
14714        Configuration ci;
14715        synchronized(this) {
14716            ci = new Configuration(mConfiguration);
14717        }
14718        return ci;
14719    }
14720
14721    public void updatePersistentConfiguration(Configuration values) {
14722        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14723                "updateConfiguration()");
14724        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14725                "updateConfiguration()");
14726        if (values == null) {
14727            throw new NullPointerException("Configuration must not be null");
14728        }
14729
14730        synchronized(this) {
14731            final long origId = Binder.clearCallingIdentity();
14732            updateConfigurationLocked(values, null, true, false);
14733            Binder.restoreCallingIdentity(origId);
14734        }
14735    }
14736
14737    public void updateConfiguration(Configuration values) {
14738        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14739                "updateConfiguration()");
14740
14741        synchronized(this) {
14742            if (values == null && mWindowManager != null) {
14743                // sentinel: fetch the current configuration from the window manager
14744                values = mWindowManager.computeNewConfiguration();
14745            }
14746
14747            if (mWindowManager != null) {
14748                mProcessList.applyDisplaySize(mWindowManager);
14749            }
14750
14751            final long origId = Binder.clearCallingIdentity();
14752            if (values != null) {
14753                Settings.System.clearConfiguration(values);
14754            }
14755            updateConfigurationLocked(values, null, false, false);
14756            Binder.restoreCallingIdentity(origId);
14757        }
14758    }
14759
14760    /**
14761     * Do either or both things: (1) change the current configuration, and (2)
14762     * make sure the given activity is running with the (now) current
14763     * configuration.  Returns true if the activity has been left running, or
14764     * false if <var>starting</var> is being destroyed to match the new
14765     * configuration.
14766     * @param persistent TODO
14767     */
14768    boolean updateConfigurationLocked(Configuration values,
14769            ActivityRecord starting, boolean persistent, boolean initLocale) {
14770        int changes = 0;
14771
14772        if (values != null) {
14773            Configuration newConfig = new Configuration(mConfiguration);
14774            changes = newConfig.updateFrom(values);
14775            if (changes != 0) {
14776                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14777                    Slog.i(TAG, "Updating configuration to: " + values);
14778                }
14779
14780                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14781
14782                if (values.locale != null && !initLocale) {
14783                    saveLocaleLocked(values.locale,
14784                                     !values.locale.equals(mConfiguration.locale),
14785                                     values.userSetLocale);
14786                }
14787
14788                mConfigurationSeq++;
14789                if (mConfigurationSeq <= 0) {
14790                    mConfigurationSeq = 1;
14791                }
14792                newConfig.seq = mConfigurationSeq;
14793                mConfiguration = newConfig;
14794                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14795                mUsageStatsService.noteStartConfig(newConfig);
14796
14797                final Configuration configCopy = new Configuration(mConfiguration);
14798
14799                // TODO: If our config changes, should we auto dismiss any currently
14800                // showing dialogs?
14801                mShowDialogs = shouldShowDialogs(newConfig);
14802
14803                AttributeCache ac = AttributeCache.instance();
14804                if (ac != null) {
14805                    ac.updateConfiguration(configCopy);
14806                }
14807
14808                // Make sure all resources in our process are updated
14809                // right now, so that anyone who is going to retrieve
14810                // resource values after we return will be sure to get
14811                // the new ones.  This is especially important during
14812                // boot, where the first config change needs to guarantee
14813                // all resources have that config before following boot
14814                // code is executed.
14815                mSystemThread.applyConfigurationToResources(configCopy);
14816
14817                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14818                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14819                    msg.obj = new Configuration(configCopy);
14820                    mHandler.sendMessage(msg);
14821                }
14822
14823                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14824                    ProcessRecord app = mLruProcesses.get(i);
14825                    try {
14826                        if (app.thread != null) {
14827                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14828                                    + app.processName + " new config " + mConfiguration);
14829                            app.thread.scheduleConfigurationChanged(configCopy);
14830                        }
14831                    } catch (Exception e) {
14832                    }
14833                }
14834                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14835                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14836                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14837                        | Intent.FLAG_RECEIVER_FOREGROUND);
14838                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14839                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14840                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14841                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14842                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14843                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14844                    broadcastIntentLocked(null, null, intent,
14845                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14846                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14847                }
14848            }
14849        }
14850
14851        boolean kept = true;
14852        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14853        // mainStack is null during startup.
14854        if (mainStack != null) {
14855            if (changes != 0 && starting == null) {
14856                // If the configuration changed, and the caller is not already
14857                // in the process of starting an activity, then find the top
14858                // activity to check if its configuration needs to change.
14859                starting = mainStack.topRunningActivityLocked(null);
14860            }
14861
14862            if (starting != null) {
14863                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14864                // And we need to make sure at this point that all other activities
14865                // are made visible with the correct configuration.
14866                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14867            }
14868        }
14869
14870        if (values != null && mWindowManager != null) {
14871            mWindowManager.setNewConfiguration(mConfiguration);
14872        }
14873
14874        return kept;
14875    }
14876
14877    /**
14878     * Decide based on the configuration whether we should shouw the ANR,
14879     * crash, etc dialogs.  The idea is that if there is no affordnace to
14880     * press the on-screen buttons, we shouldn't show the dialog.
14881     *
14882     * A thought: SystemUI might also want to get told about this, the Power
14883     * dialog / global actions also might want different behaviors.
14884     */
14885    private static final boolean shouldShowDialogs(Configuration config) {
14886        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14887                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14888    }
14889
14890    /**
14891     * Save the locale.  You must be inside a synchronized (this) block.
14892     */
14893    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14894        if(isDiff) {
14895            SystemProperties.set("user.language", l.getLanguage());
14896            SystemProperties.set("user.region", l.getCountry());
14897        }
14898
14899        if(isPersist) {
14900            SystemProperties.set("persist.sys.language", l.getLanguage());
14901            SystemProperties.set("persist.sys.country", l.getCountry());
14902            SystemProperties.set("persist.sys.localevar", l.getVariant());
14903        }
14904    }
14905
14906    @Override
14907    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14908        ActivityRecord srec = ActivityRecord.forToken(token);
14909        return srec != null && srec.task.affinity != null &&
14910                srec.task.affinity.equals(destAffinity);
14911    }
14912
14913    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14914            Intent resultData) {
14915
14916        synchronized (this) {
14917            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14918            if (stack != null) {
14919                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14920            }
14921            return false;
14922        }
14923    }
14924
14925    public int getLaunchedFromUid(IBinder activityToken) {
14926        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14927        if (srec == null) {
14928            return -1;
14929        }
14930        return srec.launchedFromUid;
14931    }
14932
14933    public String getLaunchedFromPackage(IBinder activityToken) {
14934        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14935        if (srec == null) {
14936            return null;
14937        }
14938        return srec.launchedFromPackage;
14939    }
14940
14941    // =========================================================
14942    // LIFETIME MANAGEMENT
14943    // =========================================================
14944
14945    // Returns which broadcast queue the app is the current [or imminent] receiver
14946    // on, or 'null' if the app is not an active broadcast recipient.
14947    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14948        BroadcastRecord r = app.curReceiver;
14949        if (r != null) {
14950            return r.queue;
14951        }
14952
14953        // It's not the current receiver, but it might be starting up to become one
14954        synchronized (this) {
14955            for (BroadcastQueue queue : mBroadcastQueues) {
14956                r = queue.mPendingBroadcast;
14957                if (r != null && r.curApp == app) {
14958                    // found it; report which queue it's in
14959                    return queue;
14960                }
14961            }
14962        }
14963
14964        return null;
14965    }
14966
14967    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14968            boolean doingAll, long now) {
14969        if (mAdjSeq == app.adjSeq) {
14970            // This adjustment has already been computed.
14971            return app.curRawAdj;
14972        }
14973
14974        if (app.thread == null) {
14975            app.adjSeq = mAdjSeq;
14976            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14977            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14978            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14979        }
14980
14981        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14982        app.adjSource = null;
14983        app.adjTarget = null;
14984        app.empty = false;
14985        app.cached = false;
14986
14987        final int activitiesSize = app.activities.size();
14988
14989        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14990            // The max adjustment doesn't allow this app to be anything
14991            // below foreground, so it is not worth doing work for it.
14992            app.adjType = "fixed";
14993            app.adjSeq = mAdjSeq;
14994            app.curRawAdj = app.maxAdj;
14995            app.foregroundActivities = false;
14996            app.keeping = true;
14997            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14998            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14999            // System processes can do UI, and when they do we want to have
15000            // them trim their memory after the user leaves the UI.  To
15001            // facilitate this, here we need to determine whether or not it
15002            // is currently showing UI.
15003            app.systemNoUi = true;
15004            if (app == TOP_APP) {
15005                app.systemNoUi = false;
15006            } else if (activitiesSize > 0) {
15007                for (int j = 0; j < activitiesSize; j++) {
15008                    final ActivityRecord r = app.activities.get(j);
15009                    if (r.visible) {
15010                        app.systemNoUi = false;
15011                    }
15012                }
15013            }
15014            if (!app.systemNoUi) {
15015                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15016            }
15017            return (app.curAdj=app.maxAdj);
15018        }
15019
15020        app.keeping = false;
15021        app.systemNoUi = false;
15022
15023        // Determine the importance of the process, starting with most
15024        // important to least, and assign an appropriate OOM adjustment.
15025        int adj;
15026        int schedGroup;
15027        int procState;
15028        boolean foregroundActivities = false;
15029        BroadcastQueue queue;
15030        if (app == TOP_APP) {
15031            // The last app on the list is the foreground app.
15032            adj = ProcessList.FOREGROUND_APP_ADJ;
15033            schedGroup = Process.THREAD_GROUP_DEFAULT;
15034            app.adjType = "top-activity";
15035            foregroundActivities = true;
15036            procState = ActivityManager.PROCESS_STATE_TOP;
15037        } else if (app.instrumentationClass != null) {
15038            // Don't want to kill running instrumentation.
15039            adj = ProcessList.FOREGROUND_APP_ADJ;
15040            schedGroup = Process.THREAD_GROUP_DEFAULT;
15041            app.adjType = "instrumentation";
15042            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15043        } else if ((queue = isReceivingBroadcast(app)) != null) {
15044            // An app that is currently receiving a broadcast also
15045            // counts as being in the foreground for OOM killer purposes.
15046            // It's placed in a sched group based on the nature of the
15047            // broadcast as reflected by which queue it's active in.
15048            adj = ProcessList.FOREGROUND_APP_ADJ;
15049            schedGroup = (queue == mFgBroadcastQueue)
15050                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15051            app.adjType = "broadcast";
15052            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15053        } else if (app.executingServices.size() > 0) {
15054            // An app that is currently executing a service callback also
15055            // counts as being in the foreground.
15056            adj = ProcessList.FOREGROUND_APP_ADJ;
15057            schedGroup = app.execServicesFg ?
15058                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15059            app.adjType = "exec-service";
15060            procState = ActivityManager.PROCESS_STATE_SERVICE;
15061            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15062        } else {
15063            // As far as we know the process is empty.  We may change our mind later.
15064            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15065            // At this point we don't actually know the adjustment.  Use the cached adj
15066            // value that the caller wants us to.
15067            adj = cachedAdj;
15068            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15069            app.cached = true;
15070            app.empty = true;
15071            app.adjType = "cch-empty";
15072        }
15073
15074        // Examine all activities if not already foreground.
15075        if (!foregroundActivities && activitiesSize > 0) {
15076            for (int j = 0; j < activitiesSize; j++) {
15077                final ActivityRecord r = app.activities.get(j);
15078                if (r.app != app) {
15079                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15080                            + app + "?!?");
15081                    continue;
15082                }
15083                if (r.visible) {
15084                    // App has a visible activity; only upgrade adjustment.
15085                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15086                        adj = ProcessList.VISIBLE_APP_ADJ;
15087                        app.adjType = "visible";
15088                    }
15089                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15090                        procState = ActivityManager.PROCESS_STATE_TOP;
15091                    }
15092                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15093                    app.cached = false;
15094                    app.empty = false;
15095                    foregroundActivities = true;
15096                    break;
15097                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15098                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15099                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15100                        app.adjType = "pausing";
15101                    }
15102                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15103                        procState = ActivityManager.PROCESS_STATE_TOP;
15104                    }
15105                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15106                    app.cached = false;
15107                    app.empty = false;
15108                    foregroundActivities = true;
15109                } else if (r.state == ActivityState.STOPPING) {
15110                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15111                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15112                        app.adjType = "stopping";
15113                    }
15114                    // For the process state, we will at this point consider the
15115                    // process to be cached.  It will be cached either as an activity
15116                    // or empty depending on whether the activity is finishing.  We do
15117                    // this so that we can treat the process as cached for purposes of
15118                    // memory trimming (determing current memory level, trim command to
15119                    // send to process) since there can be an arbitrary number of stopping
15120                    // processes and they should soon all go into the cached state.
15121                    if (!r.finishing) {
15122                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15123                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15124                        }
15125                    }
15126                    app.cached = false;
15127                    app.empty = false;
15128                    foregroundActivities = true;
15129                } else {
15130                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15131                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15132                        app.adjType = "cch-act";
15133                    }
15134                }
15135            }
15136        }
15137
15138        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15139            if (app.foregroundServices) {
15140                // The user is aware of this app, so make it visible.
15141                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15142                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15143                app.cached = false;
15144                app.adjType = "fg-service";
15145                schedGroup = Process.THREAD_GROUP_DEFAULT;
15146            } else if (app.forcingToForeground != null) {
15147                // The user is aware of this app, so make it visible.
15148                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15149                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15150                app.cached = false;
15151                app.adjType = "force-fg";
15152                app.adjSource = app.forcingToForeground;
15153                schedGroup = Process.THREAD_GROUP_DEFAULT;
15154            }
15155        }
15156
15157        if (app == mHeavyWeightProcess) {
15158            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15159                // We don't want to kill the current heavy-weight process.
15160                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15161                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15162                app.cached = false;
15163                app.adjType = "heavy";
15164            }
15165            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15166                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15167            }
15168        }
15169
15170        if (app == mHomeProcess) {
15171            if (adj > ProcessList.HOME_APP_ADJ) {
15172                // This process is hosting what we currently consider to be the
15173                // home app, so we don't want to let it go into the background.
15174                adj = ProcessList.HOME_APP_ADJ;
15175                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15176                app.cached = false;
15177                app.adjType = "home";
15178            }
15179            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15180                procState = ActivityManager.PROCESS_STATE_HOME;
15181            }
15182        }
15183
15184        if (app == mPreviousProcess && app.activities.size() > 0) {
15185            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15186                // This was the previous process that showed UI to the user.
15187                // We want to try to keep it around more aggressively, to give
15188                // a good experience around switching between two apps.
15189                adj = ProcessList.PREVIOUS_APP_ADJ;
15190                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15191                app.cached = false;
15192                app.adjType = "previous";
15193            }
15194            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15195                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15196            }
15197        }
15198
15199        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15200                + " reason=" + app.adjType);
15201
15202        // By default, we use the computed adjustment.  It may be changed if
15203        // there are applications dependent on our services or providers, but
15204        // this gives us a baseline and makes sure we don't get into an
15205        // infinite recursion.
15206        app.adjSeq = mAdjSeq;
15207        app.curRawAdj = adj;
15208        app.hasStartedServices = false;
15209
15210        if (mBackupTarget != null && app == mBackupTarget.app) {
15211            // If possible we want to avoid killing apps while they're being backed up
15212            if (adj > ProcessList.BACKUP_APP_ADJ) {
15213                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15214                adj = ProcessList.BACKUP_APP_ADJ;
15215                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15216                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15217                }
15218                app.adjType = "backup";
15219                app.cached = false;
15220            }
15221            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15222                procState = ActivityManager.PROCESS_STATE_BACKUP;
15223            }
15224        }
15225
15226        boolean mayBeTop = false;
15227
15228        for (int is = app.services.size()-1;
15229                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15230                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15231                        || procState > ActivityManager.PROCESS_STATE_TOP);
15232                is--) {
15233            ServiceRecord s = app.services.valueAt(is);
15234            if (s.startRequested) {
15235                app.hasStartedServices = true;
15236                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15237                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15238                }
15239                if (app.hasShownUi && app != mHomeProcess) {
15240                    // If this process has shown some UI, let it immediately
15241                    // go to the LRU list because it may be pretty heavy with
15242                    // UI stuff.  We'll tag it with a label just to help
15243                    // debug and understand what is going on.
15244                    if (adj > ProcessList.SERVICE_ADJ) {
15245                        app.adjType = "cch-started-ui-services";
15246                    }
15247                } else {
15248                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15249                        // This service has seen some activity within
15250                        // recent memory, so we will keep its process ahead
15251                        // of the background processes.
15252                        if (adj > ProcessList.SERVICE_ADJ) {
15253                            adj = ProcessList.SERVICE_ADJ;
15254                            app.adjType = "started-services";
15255                            app.cached = false;
15256                        }
15257                    }
15258                    // If we have let the service slide into the background
15259                    // state, still have some text describing what it is doing
15260                    // even though the service no longer has an impact.
15261                    if (adj > ProcessList.SERVICE_ADJ) {
15262                        app.adjType = "cch-started-services";
15263                    }
15264                }
15265                // Don't kill this process because it is doing work; it
15266                // has said it is doing work.
15267                app.keeping = true;
15268            }
15269            for (int conni = s.connections.size()-1;
15270                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15271                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15272                            || procState > ActivityManager.PROCESS_STATE_TOP);
15273                    conni--) {
15274                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15275                for (int i = 0;
15276                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15277                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15278                                || procState > ActivityManager.PROCESS_STATE_TOP);
15279                        i++) {
15280                    // XXX should compute this based on the max of
15281                    // all connected clients.
15282                    ConnectionRecord cr = clist.get(i);
15283                    if (cr.binding.client == app) {
15284                        // Binding to ourself is not interesting.
15285                        continue;
15286                    }
15287                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15288                        ProcessRecord client = cr.binding.client;
15289                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15290                                TOP_APP, doingAll, now);
15291                        int clientProcState = client.curProcState;
15292                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15293                            // If the other app is cached for any reason, for purposes here
15294                            // we are going to consider it empty.  The specific cached state
15295                            // doesn't propagate except under certain conditions.
15296                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15297                        }
15298                        String adjType = null;
15299                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15300                            // Not doing bind OOM management, so treat
15301                            // this guy more like a started service.
15302                            if (app.hasShownUi && app != mHomeProcess) {
15303                                // If this process has shown some UI, let it immediately
15304                                // go to the LRU list because it may be pretty heavy with
15305                                // UI stuff.  We'll tag it with a label just to help
15306                                // debug and understand what is going on.
15307                                if (adj > clientAdj) {
15308                                    adjType = "cch-bound-ui-services";
15309                                }
15310                                app.cached = false;
15311                                clientAdj = adj;
15312                                clientProcState = procState;
15313                            } else {
15314                                if (now >= (s.lastActivity
15315                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15316                                    // This service has not seen activity within
15317                                    // recent memory, so allow it to drop to the
15318                                    // LRU list if there is no other reason to keep
15319                                    // it around.  We'll also tag it with a label just
15320                                    // to help debug and undertand what is going on.
15321                                    if (adj > clientAdj) {
15322                                        adjType = "cch-bound-services";
15323                                    }
15324                                    clientAdj = adj;
15325                                }
15326                            }
15327                        }
15328                        if (adj > clientAdj) {
15329                            // If this process has recently shown UI, and
15330                            // the process that is binding to it is less
15331                            // important than being visible, then we don't
15332                            // care about the binding as much as we care
15333                            // about letting this process get into the LRU
15334                            // list to be killed and restarted if needed for
15335                            // memory.
15336                            if (app.hasShownUi && app != mHomeProcess
15337                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15338                                adjType = "cch-bound-ui-services";
15339                            } else {
15340                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15341                                        |Context.BIND_IMPORTANT)) != 0) {
15342                                    adj = clientAdj;
15343                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15344                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15345                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15346                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15347                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15348                                    adj = clientAdj;
15349                                } else {
15350                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15351                                        adj = ProcessList.VISIBLE_APP_ADJ;
15352                                    }
15353                                }
15354                                if (!client.cached) {
15355                                    app.cached = false;
15356                                }
15357                                if (client.keeping) {
15358                                    app.keeping = true;
15359                                }
15360                                adjType = "service";
15361                            }
15362                        }
15363                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15364                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15365                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15366                            }
15367                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15368                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15369                                    // Special handling of clients who are in the top state.
15370                                    // We *may* want to consider this process to be in the
15371                                    // top state as well, but only if there is not another
15372                                    // reason for it to be running.  Being on the top is a
15373                                    // special state, meaning you are specifically running
15374                                    // for the current top app.  If the process is already
15375                                    // running in the background for some other reason, it
15376                                    // is more important to continue considering it to be
15377                                    // in the background state.
15378                                    mayBeTop = true;
15379                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15380                                } else {
15381                                    // Special handling for above-top states (persistent
15382                                    // processes).  These should not bring the current process
15383                                    // into the top state, since they are not on top.  Instead
15384                                    // give them the best state after that.
15385                                    clientProcState =
15386                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15387                                }
15388                            }
15389                        } else {
15390                            if (clientProcState <
15391                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15392                                clientProcState =
15393                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15394                            }
15395                        }
15396                        if (procState > clientProcState) {
15397                            procState = clientProcState;
15398                        }
15399                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15400                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15401                            app.pendingUiClean = true;
15402                        }
15403                        if (adjType != null) {
15404                            app.adjType = adjType;
15405                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15406                                    .REASON_SERVICE_IN_USE;
15407                            app.adjSource = cr.binding.client;
15408                            app.adjSourceOom = clientAdj;
15409                            app.adjTarget = s.name;
15410                        }
15411                    }
15412                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15413                        app.treatLikeActivity = true;
15414                    }
15415                    final ActivityRecord a = cr.activity;
15416                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15417                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15418                                (a.visible || a.state == ActivityState.RESUMED
15419                                 || a.state == ActivityState.PAUSING)) {
15420                            adj = ProcessList.FOREGROUND_APP_ADJ;
15421                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15422                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15423                            }
15424                            app.cached = false;
15425                            app.adjType = "service";
15426                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15427                                    .REASON_SERVICE_IN_USE;
15428                            app.adjSource = a;
15429                            app.adjSourceOom = adj;
15430                            app.adjTarget = s.name;
15431                        }
15432                    }
15433                }
15434            }
15435        }
15436
15437        for (int provi = app.pubProviders.size()-1;
15438                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15439                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15440                        || procState > ActivityManager.PROCESS_STATE_TOP);
15441                provi--) {
15442            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15443            for (int i = cpr.connections.size()-1;
15444                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15445                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15446                            || procState > ActivityManager.PROCESS_STATE_TOP);
15447                    i--) {
15448                ContentProviderConnection conn = cpr.connections.get(i);
15449                ProcessRecord client = conn.client;
15450                if (client == app) {
15451                    // Being our own client is not interesting.
15452                    continue;
15453                }
15454                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15455                int clientProcState = client.curProcState;
15456                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15457                    // If the other app is cached for any reason, for purposes here
15458                    // we are going to consider it empty.
15459                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15460                }
15461                if (adj > clientAdj) {
15462                    if (app.hasShownUi && app != mHomeProcess
15463                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15464                        app.adjType = "cch-ui-provider";
15465                    } else {
15466                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15467                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15468                        app.adjType = "provider";
15469                    }
15470                    app.cached &= client.cached;
15471                    app.keeping |= client.keeping;
15472                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15473                            .REASON_PROVIDER_IN_USE;
15474                    app.adjSource = client;
15475                    app.adjSourceOom = clientAdj;
15476                    app.adjTarget = cpr.name;
15477                }
15478                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15479                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15480                        // Special handling of clients who are in the top state.
15481                        // We *may* want to consider this process to be in the
15482                        // top state as well, but only if there is not another
15483                        // reason for it to be running.  Being on the top is a
15484                        // special state, meaning you are specifically running
15485                        // for the current top app.  If the process is already
15486                        // running in the background for some other reason, it
15487                        // is more important to continue considering it to be
15488                        // in the background state.
15489                        mayBeTop = true;
15490                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15491                    } else {
15492                        // Special handling for above-top states (persistent
15493                        // processes).  These should not bring the current process
15494                        // into the top state, since they are not on top.  Instead
15495                        // give them the best state after that.
15496                        clientProcState =
15497                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15498                    }
15499                }
15500                if (procState > clientProcState) {
15501                    procState = clientProcState;
15502                }
15503                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15504                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15505                }
15506            }
15507            // If the provider has external (non-framework) process
15508            // dependencies, ensure that its adjustment is at least
15509            // FOREGROUND_APP_ADJ.
15510            if (cpr.hasExternalProcessHandles()) {
15511                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15512                    adj = ProcessList.FOREGROUND_APP_ADJ;
15513                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15514                    app.cached = false;
15515                    app.keeping = true;
15516                    app.adjType = "provider";
15517                    app.adjTarget = cpr.name;
15518                }
15519                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15520                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15521                }
15522            }
15523        }
15524
15525        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15526            // A client of one of our services or providers is in the top state.  We
15527            // *may* want to be in the top state, but not if we are already running in
15528            // the background for some other reason.  For the decision here, we are going
15529            // to pick out a few specific states that we want to remain in when a client
15530            // is top (states that tend to be longer-term) and otherwise allow it to go
15531            // to the top state.
15532            switch (procState) {
15533                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15534                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15535                case ActivityManager.PROCESS_STATE_SERVICE:
15536                    // These all are longer-term states, so pull them up to the top
15537                    // of the background states, but not all the way to the top state.
15538                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15539                    break;
15540                default:
15541                    // Otherwise, top is a better choice, so take it.
15542                    procState = ActivityManager.PROCESS_STATE_TOP;
15543                    break;
15544            }
15545        }
15546
15547        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15548            if (app.hasClientActivities) {
15549                // This is a cached process, but with client activities.  Mark it so.
15550                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15551                app.adjType = "cch-client-act";
15552            } else if (app.treatLikeActivity) {
15553                // This is a cached process, but somebody wants us to treat it like it has
15554                // an activity, okay!
15555                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15556                app.adjType = "cch-as-act";
15557            }
15558        }
15559
15560        if (adj == ProcessList.SERVICE_ADJ) {
15561            if (doingAll) {
15562                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15563                mNewNumServiceProcs++;
15564                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15565                if (!app.serviceb) {
15566                    // This service isn't far enough down on the LRU list to
15567                    // normally be a B service, but if we are low on RAM and it
15568                    // is large we want to force it down since we would prefer to
15569                    // keep launcher over it.
15570                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15571                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15572                        app.serviceHighRam = true;
15573                        app.serviceb = true;
15574                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15575                    } else {
15576                        mNewNumAServiceProcs++;
15577                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15578                    }
15579                } else {
15580                    app.serviceHighRam = false;
15581                }
15582            }
15583            if (app.serviceb) {
15584                adj = ProcessList.SERVICE_B_ADJ;
15585            }
15586        }
15587
15588        app.curRawAdj = adj;
15589
15590        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15591        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15592        if (adj > app.maxAdj) {
15593            adj = app.maxAdj;
15594            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15595                schedGroup = Process.THREAD_GROUP_DEFAULT;
15596            }
15597        }
15598        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15599            app.keeping = true;
15600        }
15601
15602        // Do final modification to adj.  Everything we do between here and applying
15603        // the final setAdj must be done in this function, because we will also use
15604        // it when computing the final cached adj later.  Note that we don't need to
15605        // worry about this for max adj above, since max adj will always be used to
15606        // keep it out of the cached vaues.
15607        app.curAdj = app.modifyRawOomAdj(adj);
15608        app.curSchedGroup = schedGroup;
15609        app.curProcState = procState;
15610        app.foregroundActivities = foregroundActivities;
15611
15612        return app.curRawAdj;
15613    }
15614
15615    /**
15616     * Schedule PSS collection of a process.
15617     */
15618    void requestPssLocked(ProcessRecord proc, int procState) {
15619        if (mPendingPssProcesses.contains(proc)) {
15620            return;
15621        }
15622        if (mPendingPssProcesses.size() == 0) {
15623            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15624        }
15625        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15626        proc.pssProcState = procState;
15627        mPendingPssProcesses.add(proc);
15628    }
15629
15630    /**
15631     * Schedule PSS collection of all processes.
15632     */
15633    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15634        if (!always) {
15635            if (now < (mLastFullPssTime +
15636                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15637                return;
15638            }
15639        }
15640        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15641        mLastFullPssTime = now;
15642        mFullPssPending = true;
15643        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15644        mPendingPssProcesses.clear();
15645        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15646            ProcessRecord app = mLruProcesses.get(i);
15647            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15648                app.pssProcState = app.setProcState;
15649                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15650                        isSleeping(), now);
15651                mPendingPssProcesses.add(app);
15652            }
15653        }
15654        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15655    }
15656
15657    /**
15658     * Ask a given process to GC right now.
15659     */
15660    final void performAppGcLocked(ProcessRecord app) {
15661        try {
15662            app.lastRequestedGc = SystemClock.uptimeMillis();
15663            if (app.thread != null) {
15664                if (app.reportLowMemory) {
15665                    app.reportLowMemory = false;
15666                    app.thread.scheduleLowMemory();
15667                } else {
15668                    app.thread.processInBackground();
15669                }
15670            }
15671        } catch (Exception e) {
15672            // whatever.
15673        }
15674    }
15675
15676    /**
15677     * Returns true if things are idle enough to perform GCs.
15678     */
15679    private final boolean canGcNowLocked() {
15680        boolean processingBroadcasts = false;
15681        for (BroadcastQueue q : mBroadcastQueues) {
15682            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15683                processingBroadcasts = true;
15684            }
15685        }
15686        return !processingBroadcasts
15687                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15688    }
15689
15690    /**
15691     * Perform GCs on all processes that are waiting for it, but only
15692     * if things are idle.
15693     */
15694    final void performAppGcsLocked() {
15695        final int N = mProcessesToGc.size();
15696        if (N <= 0) {
15697            return;
15698        }
15699        if (canGcNowLocked()) {
15700            while (mProcessesToGc.size() > 0) {
15701                ProcessRecord proc = mProcessesToGc.remove(0);
15702                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15703                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15704                            <= SystemClock.uptimeMillis()) {
15705                        // To avoid spamming the system, we will GC processes one
15706                        // at a time, waiting a few seconds between each.
15707                        performAppGcLocked(proc);
15708                        scheduleAppGcsLocked();
15709                        return;
15710                    } else {
15711                        // It hasn't been long enough since we last GCed this
15712                        // process...  put it in the list to wait for its time.
15713                        addProcessToGcListLocked(proc);
15714                        break;
15715                    }
15716                }
15717            }
15718
15719            scheduleAppGcsLocked();
15720        }
15721    }
15722
15723    /**
15724     * If all looks good, perform GCs on all processes waiting for them.
15725     */
15726    final void performAppGcsIfAppropriateLocked() {
15727        if (canGcNowLocked()) {
15728            performAppGcsLocked();
15729            return;
15730        }
15731        // Still not idle, wait some more.
15732        scheduleAppGcsLocked();
15733    }
15734
15735    /**
15736     * Schedule the execution of all pending app GCs.
15737     */
15738    final void scheduleAppGcsLocked() {
15739        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15740
15741        if (mProcessesToGc.size() > 0) {
15742            // Schedule a GC for the time to the next process.
15743            ProcessRecord proc = mProcessesToGc.get(0);
15744            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15745
15746            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15747            long now = SystemClock.uptimeMillis();
15748            if (when < (now+GC_TIMEOUT)) {
15749                when = now + GC_TIMEOUT;
15750            }
15751            mHandler.sendMessageAtTime(msg, when);
15752        }
15753    }
15754
15755    /**
15756     * Add a process to the array of processes waiting to be GCed.  Keeps the
15757     * list in sorted order by the last GC time.  The process can't already be
15758     * on the list.
15759     */
15760    final void addProcessToGcListLocked(ProcessRecord proc) {
15761        boolean added = false;
15762        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15763            if (mProcessesToGc.get(i).lastRequestedGc <
15764                    proc.lastRequestedGc) {
15765                added = true;
15766                mProcessesToGc.add(i+1, proc);
15767                break;
15768            }
15769        }
15770        if (!added) {
15771            mProcessesToGc.add(0, proc);
15772        }
15773    }
15774
15775    /**
15776     * Set up to ask a process to GC itself.  This will either do it
15777     * immediately, or put it on the list of processes to gc the next
15778     * time things are idle.
15779     */
15780    final void scheduleAppGcLocked(ProcessRecord app) {
15781        long now = SystemClock.uptimeMillis();
15782        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15783            return;
15784        }
15785        if (!mProcessesToGc.contains(app)) {
15786            addProcessToGcListLocked(app);
15787            scheduleAppGcsLocked();
15788        }
15789    }
15790
15791    final void checkExcessivePowerUsageLocked(boolean doKills) {
15792        updateCpuStatsNow();
15793
15794        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15795        boolean doWakeKills = doKills;
15796        boolean doCpuKills = doKills;
15797        if (mLastPowerCheckRealtime == 0) {
15798            doWakeKills = false;
15799        }
15800        if (mLastPowerCheckUptime == 0) {
15801            doCpuKills = false;
15802        }
15803        if (stats.isScreenOn()) {
15804            doWakeKills = false;
15805        }
15806        final long curRealtime = SystemClock.elapsedRealtime();
15807        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15808        final long curUptime = SystemClock.uptimeMillis();
15809        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15810        mLastPowerCheckRealtime = curRealtime;
15811        mLastPowerCheckUptime = curUptime;
15812        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15813            doWakeKills = false;
15814        }
15815        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15816            doCpuKills = false;
15817        }
15818        int i = mLruProcesses.size();
15819        while (i > 0) {
15820            i--;
15821            ProcessRecord app = mLruProcesses.get(i);
15822            if (!app.keeping) {
15823                long wtime;
15824                synchronized (stats) {
15825                    wtime = stats.getProcessWakeTime(app.info.uid,
15826                            app.pid, curRealtime);
15827                }
15828                long wtimeUsed = wtime - app.lastWakeTime;
15829                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15830                if (DEBUG_POWER) {
15831                    StringBuilder sb = new StringBuilder(128);
15832                    sb.append("Wake for ");
15833                    app.toShortString(sb);
15834                    sb.append(": over ");
15835                    TimeUtils.formatDuration(realtimeSince, sb);
15836                    sb.append(" used ");
15837                    TimeUtils.formatDuration(wtimeUsed, sb);
15838                    sb.append(" (");
15839                    sb.append((wtimeUsed*100)/realtimeSince);
15840                    sb.append("%)");
15841                    Slog.i(TAG, sb.toString());
15842                    sb.setLength(0);
15843                    sb.append("CPU for ");
15844                    app.toShortString(sb);
15845                    sb.append(": over ");
15846                    TimeUtils.formatDuration(uptimeSince, sb);
15847                    sb.append(" used ");
15848                    TimeUtils.formatDuration(cputimeUsed, sb);
15849                    sb.append(" (");
15850                    sb.append((cputimeUsed*100)/uptimeSince);
15851                    sb.append("%)");
15852                    Slog.i(TAG, sb.toString());
15853                }
15854                // If a process has held a wake lock for more
15855                // than 50% of the time during this period,
15856                // that sounds bad.  Kill!
15857                if (doWakeKills && realtimeSince > 0
15858                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15859                    synchronized (stats) {
15860                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15861                                realtimeSince, wtimeUsed);
15862                    }
15863                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15864                            + " during " + realtimeSince);
15865                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15866                } else if (doCpuKills && uptimeSince > 0
15867                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15868                    synchronized (stats) {
15869                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15870                                uptimeSince, cputimeUsed);
15871                    }
15872                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15873                            + " during " + uptimeSince);
15874                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15875                } else {
15876                    app.lastWakeTime = wtime;
15877                    app.lastCpuTime = app.curCpuTime;
15878                }
15879            }
15880        }
15881    }
15882
15883    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15884            ProcessRecord TOP_APP, boolean doingAll, long now) {
15885        boolean success = true;
15886
15887        if (app.curRawAdj != app.setRawAdj) {
15888            if (wasKeeping && !app.keeping) {
15889                // This app is no longer something we want to keep.  Note
15890                // its current wake lock time to later know to kill it if
15891                // it is not behaving well.
15892                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15893                synchronized (stats) {
15894                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15895                            app.pid, SystemClock.elapsedRealtime());
15896                }
15897                app.lastCpuTime = app.curCpuTime;
15898            }
15899
15900            app.setRawAdj = app.curRawAdj;
15901        }
15902
15903        int changes = 0;
15904
15905        if (app.curAdj != app.setAdj) {
15906            ProcessList.setOomAdj(app.pid, app.curAdj);
15907            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15908                TAG, "Set " + app.pid + " " + app.processName +
15909                " adj " + app.curAdj + ": " + app.adjType);
15910            app.setAdj = app.curAdj;
15911        }
15912
15913        if (app.setSchedGroup != app.curSchedGroup) {
15914            app.setSchedGroup = app.curSchedGroup;
15915            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15916                    "Setting process group of " + app.processName
15917                    + " to " + app.curSchedGroup);
15918            if (app.waitingToKill != null &&
15919                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15920                killUnneededProcessLocked(app, app.waitingToKill);
15921                success = false;
15922            } else {
15923                if (true) {
15924                    long oldId = Binder.clearCallingIdentity();
15925                    try {
15926                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15927                    } catch (Exception e) {
15928                        Slog.w(TAG, "Failed setting process group of " + app.pid
15929                                + " to " + app.curSchedGroup);
15930                        e.printStackTrace();
15931                    } finally {
15932                        Binder.restoreCallingIdentity(oldId);
15933                    }
15934                } else {
15935                    if (app.thread != null) {
15936                        try {
15937                            app.thread.setSchedulingGroup(app.curSchedGroup);
15938                        } catch (RemoteException e) {
15939                        }
15940                    }
15941                }
15942                Process.setSwappiness(app.pid,
15943                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15944            }
15945        }
15946        if (app.repForegroundActivities != app.foregroundActivities) {
15947            app.repForegroundActivities = app.foregroundActivities;
15948            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15949        }
15950        if (app.repProcState != app.curProcState) {
15951            app.repProcState = app.curProcState;
15952            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15953            if (app.thread != null) {
15954                try {
15955                    if (false) {
15956                        //RuntimeException h = new RuntimeException("here");
15957                        Slog.i(TAG, "Sending new process state " + app.repProcState
15958                                + " to " + app /*, h*/);
15959                    }
15960                    app.thread.setProcessState(app.repProcState);
15961                } catch (RemoteException e) {
15962                }
15963            }
15964        }
15965        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15966                app.setProcState)) {
15967            app.lastStateTime = now;
15968            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15969                    isSleeping(), now);
15970            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15971                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15972                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15973                    + (app.nextPssTime-now) + ": " + app);
15974        } else {
15975            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15976                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15977                requestPssLocked(app, app.setProcState);
15978                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15979                        isSleeping(), now);
15980            } else if (false && DEBUG_PSS) {
15981                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15982            }
15983        }
15984        if (app.setProcState != app.curProcState) {
15985            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15986                    "Proc state change of " + app.processName
15987                    + " to " + app.curProcState);
15988            app.setProcState = app.curProcState;
15989            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15990                app.notCachedSinceIdle = false;
15991            }
15992            if (!doingAll) {
15993                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15994            } else {
15995                app.procStateChanged = true;
15996            }
15997        }
15998
15999        if (changes != 0) {
16000            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16001            int i = mPendingProcessChanges.size()-1;
16002            ProcessChangeItem item = null;
16003            while (i >= 0) {
16004                item = mPendingProcessChanges.get(i);
16005                if (item.pid == app.pid) {
16006                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16007                    break;
16008                }
16009                i--;
16010            }
16011            if (i < 0) {
16012                // No existing item in pending changes; need a new one.
16013                final int NA = mAvailProcessChanges.size();
16014                if (NA > 0) {
16015                    item = mAvailProcessChanges.remove(NA-1);
16016                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16017                } else {
16018                    item = new ProcessChangeItem();
16019                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16020                }
16021                item.changes = 0;
16022                item.pid = app.pid;
16023                item.uid = app.info.uid;
16024                if (mPendingProcessChanges.size() == 0) {
16025                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16026                            "*** Enqueueing dispatch processes changed!");
16027                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16028                }
16029                mPendingProcessChanges.add(item);
16030            }
16031            item.changes |= changes;
16032            item.processState = app.repProcState;
16033            item.foregroundActivities = app.repForegroundActivities;
16034            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16035                    + Integer.toHexString(System.identityHashCode(item))
16036                    + " " + app.toShortString() + ": changes=" + item.changes
16037                    + " procState=" + item.processState
16038                    + " foreground=" + item.foregroundActivities
16039                    + " type=" + app.adjType + " source=" + app.adjSource
16040                    + " target=" + app.adjTarget);
16041        }
16042
16043        return success;
16044    }
16045
16046    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
16047        if (proc.thread != null && proc.baseProcessTracker != null) {
16048            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16049        }
16050    }
16051
16052    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16053            ProcessRecord TOP_APP, boolean doingAll, long now) {
16054        if (app.thread == null) {
16055            return false;
16056        }
16057
16058        final boolean wasKeeping = app.keeping;
16059
16060        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16061
16062        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16063    }
16064
16065    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16066            boolean oomAdj) {
16067        if (isForeground != proc.foregroundServices) {
16068            proc.foregroundServices = isForeground;
16069            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16070                    proc.info.uid);
16071            if (isForeground) {
16072                if (curProcs == null) {
16073                    curProcs = new ArrayList<ProcessRecord>();
16074                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16075                }
16076                if (!curProcs.contains(proc)) {
16077                    curProcs.add(proc);
16078                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16079                            proc.info.packageName, proc.info.uid);
16080                }
16081            } else {
16082                if (curProcs != null) {
16083                    if (curProcs.remove(proc)) {
16084                        mBatteryStatsService.noteEvent(
16085                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16086                                proc.info.packageName, proc.info.uid);
16087                        if (curProcs.size() <= 0) {
16088                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16089                        }
16090                    }
16091                }
16092            }
16093            if (oomAdj) {
16094                updateOomAdjLocked();
16095            }
16096        }
16097    }
16098
16099    private final ActivityRecord resumedAppLocked() {
16100        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16101        String pkg;
16102        int uid;
16103        if (act != null && !act.sleeping) {
16104            pkg = act.packageName;
16105            uid = act.info.applicationInfo.uid;
16106        } else {
16107            pkg = null;
16108            uid = -1;
16109        }
16110        // Has the UID or resumed package name changed?
16111        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16112                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16113            if (mCurResumedPackage != null) {
16114                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16115                        mCurResumedPackage, mCurResumedUid);
16116            }
16117            mCurResumedPackage = pkg;
16118            mCurResumedUid = uid;
16119            if (mCurResumedPackage != null) {
16120                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16121                        mCurResumedPackage, mCurResumedUid);
16122            }
16123        }
16124        return act;
16125    }
16126
16127    final boolean updateOomAdjLocked(ProcessRecord app) {
16128        final ActivityRecord TOP_ACT = resumedAppLocked();
16129        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16130        final boolean wasCached = app.cached;
16131
16132        mAdjSeq++;
16133
16134        // This is the desired cached adjusment we want to tell it to use.
16135        // If our app is currently cached, we know it, and that is it.  Otherwise,
16136        // we don't know it yet, and it needs to now be cached we will then
16137        // need to do a complete oom adj.
16138        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16139                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16140        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16141                SystemClock.uptimeMillis());
16142        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16143            // Changed to/from cached state, so apps after it in the LRU
16144            // list may also be changed.
16145            updateOomAdjLocked();
16146        }
16147        return success;
16148    }
16149
16150    final void updateOomAdjLocked() {
16151        final ActivityRecord TOP_ACT = resumedAppLocked();
16152        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16153        final long now = SystemClock.uptimeMillis();
16154        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16155        final int N = mLruProcesses.size();
16156
16157        if (false) {
16158            RuntimeException e = new RuntimeException();
16159            e.fillInStackTrace();
16160            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16161        }
16162
16163        mAdjSeq++;
16164        mNewNumServiceProcs = 0;
16165        mNewNumAServiceProcs = 0;
16166
16167        final int emptyProcessLimit;
16168        final int cachedProcessLimit;
16169        if (mProcessLimit <= 0) {
16170            emptyProcessLimit = cachedProcessLimit = 0;
16171        } else if (mProcessLimit == 1) {
16172            emptyProcessLimit = 1;
16173            cachedProcessLimit = 0;
16174        } else {
16175            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16176            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16177        }
16178
16179        // Let's determine how many processes we have running vs.
16180        // how many slots we have for background processes; we may want
16181        // to put multiple processes in a slot of there are enough of
16182        // them.
16183        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16184                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16185        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16186        if (numEmptyProcs > cachedProcessLimit) {
16187            // If there are more empty processes than our limit on cached
16188            // processes, then use the cached process limit for the factor.
16189            // This ensures that the really old empty processes get pushed
16190            // down to the bottom, so if we are running low on memory we will
16191            // have a better chance at keeping around more cached processes
16192            // instead of a gazillion empty processes.
16193            numEmptyProcs = cachedProcessLimit;
16194        }
16195        int emptyFactor = numEmptyProcs/numSlots;
16196        if (emptyFactor < 1) emptyFactor = 1;
16197        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16198        if (cachedFactor < 1) cachedFactor = 1;
16199        int stepCached = 0;
16200        int stepEmpty = 0;
16201        int numCached = 0;
16202        int numEmpty = 0;
16203        int numTrimming = 0;
16204
16205        mNumNonCachedProcs = 0;
16206        mNumCachedHiddenProcs = 0;
16207
16208        // First update the OOM adjustment for each of the
16209        // application processes based on their current state.
16210        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16211        int nextCachedAdj = curCachedAdj+1;
16212        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16213        int nextEmptyAdj = curEmptyAdj+2;
16214        for (int i=N-1; i>=0; i--) {
16215            ProcessRecord app = mLruProcesses.get(i);
16216            if (!app.killedByAm && app.thread != null) {
16217                app.procStateChanged = false;
16218                final boolean wasKeeping = app.keeping;
16219                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16220
16221                // If we haven't yet assigned the final cached adj
16222                // to the process, do that now.
16223                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16224                    switch (app.curProcState) {
16225                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16226                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16227                            // This process is a cached process holding activities...
16228                            // assign it the next cached value for that type, and then
16229                            // step that cached level.
16230                            app.curRawAdj = curCachedAdj;
16231                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16232                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16233                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16234                                    + ")");
16235                            if (curCachedAdj != nextCachedAdj) {
16236                                stepCached++;
16237                                if (stepCached >= cachedFactor) {
16238                                    stepCached = 0;
16239                                    curCachedAdj = nextCachedAdj;
16240                                    nextCachedAdj += 2;
16241                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16242                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16243                                    }
16244                                }
16245                            }
16246                            break;
16247                        default:
16248                            // For everything else, assign next empty cached process
16249                            // level and bump that up.  Note that this means that
16250                            // long-running services that have dropped down to the
16251                            // cached level will be treated as empty (since their process
16252                            // state is still as a service), which is what we want.
16253                            app.curRawAdj = curEmptyAdj;
16254                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16255                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16256                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16257                                    + ")");
16258                            if (curEmptyAdj != nextEmptyAdj) {
16259                                stepEmpty++;
16260                                if (stepEmpty >= emptyFactor) {
16261                                    stepEmpty = 0;
16262                                    curEmptyAdj = nextEmptyAdj;
16263                                    nextEmptyAdj += 2;
16264                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16265                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16266                                    }
16267                                }
16268                            }
16269                            break;
16270                    }
16271                }
16272
16273                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16274
16275                // Count the number of process types.
16276                switch (app.curProcState) {
16277                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16278                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16279                        mNumCachedHiddenProcs++;
16280                        numCached++;
16281                        if (numCached > cachedProcessLimit) {
16282                            killUnneededProcessLocked(app, "cached #" + numCached);
16283                        }
16284                        break;
16285                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16286                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16287                                && app.lastActivityTime < oldTime) {
16288                            killUnneededProcessLocked(app, "empty for "
16289                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16290                                    / 1000) + "s");
16291                        } else {
16292                            numEmpty++;
16293                            if (numEmpty > emptyProcessLimit) {
16294                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16295                            }
16296                        }
16297                        break;
16298                    default:
16299                        mNumNonCachedProcs++;
16300                        break;
16301                }
16302
16303                if (app.isolated && app.services.size() <= 0) {
16304                    // If this is an isolated process, and there are no
16305                    // services running in it, then the process is no longer
16306                    // needed.  We agressively kill these because we can by
16307                    // definition not re-use the same process again, and it is
16308                    // good to avoid having whatever code was running in them
16309                    // left sitting around after no longer needed.
16310                    killUnneededProcessLocked(app, "isolated not needed");
16311                }
16312
16313                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16314                        && !app.killedByAm) {
16315                    numTrimming++;
16316                }
16317            }
16318        }
16319
16320        mNumServiceProcs = mNewNumServiceProcs;
16321
16322        // Now determine the memory trimming level of background processes.
16323        // Unfortunately we need to start at the back of the list to do this
16324        // properly.  We only do this if the number of background apps we
16325        // are managing to keep around is less than half the maximum we desire;
16326        // if we are keeping a good number around, we'll let them use whatever
16327        // memory they want.
16328        final int numCachedAndEmpty = numCached + numEmpty;
16329        int memFactor;
16330        if (numCached <= ProcessList.TRIM_CACHED_APPS
16331                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16332            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16333                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16334            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16335                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16336            } else {
16337                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16338            }
16339        } else {
16340            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16341        }
16342        // We always allow the memory level to go up (better).  We only allow it to go
16343        // down if we are in a state where that is allowed, *and* the total number of processes
16344        // has gone down since last time.
16345        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16346                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16347                + " last=" + mLastNumProcesses);
16348        if (memFactor > mLastMemoryLevel) {
16349            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16350                memFactor = mLastMemoryLevel;
16351                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16352            }
16353        }
16354        mLastMemoryLevel = memFactor;
16355        mLastNumProcesses = mLruProcesses.size();
16356        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16357        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16358        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16359            if (mLowRamStartTime == 0) {
16360                mLowRamStartTime = now;
16361            }
16362            int step = 0;
16363            int fgTrimLevel;
16364            switch (memFactor) {
16365                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16366                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16367                    break;
16368                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16369                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16370                    break;
16371                default:
16372                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16373                    break;
16374            }
16375            int factor = numTrimming/3;
16376            int minFactor = 2;
16377            if (mHomeProcess != null) minFactor++;
16378            if (mPreviousProcess != null) minFactor++;
16379            if (factor < minFactor) factor = minFactor;
16380            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16381            for (int i=N-1; i>=0; i--) {
16382                ProcessRecord app = mLruProcesses.get(i);
16383                if (allChanged || app.procStateChanged) {
16384                    setProcessTrackerState(app, trackerMemFactor, now);
16385                    app.procStateChanged = false;
16386                }
16387                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16388                        && !app.killedByAm) {
16389                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16390                        try {
16391                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16392                                    "Trimming memory of " + app.processName
16393                                    + " to " + curLevel);
16394                            app.thread.scheduleTrimMemory(curLevel);
16395                        } catch (RemoteException e) {
16396                        }
16397                        if (false) {
16398                            // For now we won't do this; our memory trimming seems
16399                            // to be good enough at this point that destroying
16400                            // activities causes more harm than good.
16401                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16402                                    && app != mHomeProcess && app != mPreviousProcess) {
16403                                // Need to do this on its own message because the stack may not
16404                                // be in a consistent state at this point.
16405                                // For these apps we will also finish their activities
16406                                // to help them free memory.
16407                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16408                            }
16409                        }
16410                    }
16411                    app.trimMemoryLevel = curLevel;
16412                    step++;
16413                    if (step >= factor) {
16414                        step = 0;
16415                        switch (curLevel) {
16416                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16417                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16418                                break;
16419                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16420                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16421                                break;
16422                        }
16423                    }
16424                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16425                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16426                            && app.thread != null) {
16427                        try {
16428                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16429                                    "Trimming memory of heavy-weight " + app.processName
16430                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16431                            app.thread.scheduleTrimMemory(
16432                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16433                        } catch (RemoteException e) {
16434                        }
16435                    }
16436                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16437                } else {
16438                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16439                            || app.systemNoUi) && app.pendingUiClean) {
16440                        // If this application is now in the background and it
16441                        // had done UI, then give it the special trim level to
16442                        // have it free UI resources.
16443                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16444                        if (app.trimMemoryLevel < level && app.thread != null) {
16445                            try {
16446                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16447                                        "Trimming memory of bg-ui " + app.processName
16448                                        + " to " + level);
16449                                app.thread.scheduleTrimMemory(level);
16450                            } catch (RemoteException e) {
16451                            }
16452                        }
16453                        app.pendingUiClean = false;
16454                    }
16455                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16456                        try {
16457                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16458                                    "Trimming memory of fg " + app.processName
16459                                    + " to " + fgTrimLevel);
16460                            app.thread.scheduleTrimMemory(fgTrimLevel);
16461                        } catch (RemoteException e) {
16462                        }
16463                    }
16464                    app.trimMemoryLevel = fgTrimLevel;
16465                }
16466            }
16467        } else {
16468            if (mLowRamStartTime != 0) {
16469                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16470                mLowRamStartTime = 0;
16471            }
16472            for (int i=N-1; i>=0; i--) {
16473                ProcessRecord app = mLruProcesses.get(i);
16474                if (allChanged || app.procStateChanged) {
16475                    setProcessTrackerState(app, trackerMemFactor, now);
16476                    app.procStateChanged = false;
16477                }
16478                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16479                        || app.systemNoUi) && app.pendingUiClean) {
16480                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16481                            && app.thread != null) {
16482                        try {
16483                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16484                                    "Trimming memory of ui hidden " + app.processName
16485                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16486                            app.thread.scheduleTrimMemory(
16487                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16488                        } catch (RemoteException e) {
16489                        }
16490                    }
16491                    app.pendingUiClean = false;
16492                }
16493                app.trimMemoryLevel = 0;
16494            }
16495        }
16496
16497        if (mAlwaysFinishActivities) {
16498            // Need to do this on its own message because the stack may not
16499            // be in a consistent state at this point.
16500            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16501        }
16502
16503        if (allChanged) {
16504            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16505        }
16506
16507        if (mProcessStats.shouldWriteNowLocked(now)) {
16508            mHandler.post(new Runnable() {
16509                @Override public void run() {
16510                    synchronized (ActivityManagerService.this) {
16511                        mProcessStats.writeStateAsyncLocked();
16512                    }
16513                }
16514            });
16515        }
16516
16517        if (DEBUG_OOM_ADJ) {
16518            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16519        }
16520    }
16521
16522    final void trimApplications() {
16523        synchronized (this) {
16524            int i;
16525
16526            // First remove any unused application processes whose package
16527            // has been removed.
16528            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16529                final ProcessRecord app = mRemovedProcesses.get(i);
16530                if (app.activities.size() == 0
16531                        && app.curReceiver == null && app.services.size() == 0) {
16532                    Slog.i(
16533                        TAG, "Exiting empty application process "
16534                        + app.processName + " ("
16535                        + (app.thread != null ? app.thread.asBinder() : null)
16536                        + ")\n");
16537                    if (app.pid > 0 && app.pid != MY_PID) {
16538                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16539                                app.processName, app.setAdj, "empty");
16540                        app.killedByAm = true;
16541                        Process.killProcessQuiet(app.pid);
16542                    } else {
16543                        try {
16544                            app.thread.scheduleExit();
16545                        } catch (Exception e) {
16546                            // Ignore exceptions.
16547                        }
16548                    }
16549                    cleanUpApplicationRecordLocked(app, false, true, -1);
16550                    mRemovedProcesses.remove(i);
16551
16552                    if (app.persistent) {
16553                        addAppLocked(app.info, false, null /* ABI override */);
16554                    }
16555                }
16556            }
16557
16558            // Now update the oom adj for all processes.
16559            updateOomAdjLocked();
16560        }
16561    }
16562
16563    /** This method sends the specified signal to each of the persistent apps */
16564    public void signalPersistentProcesses(int sig) throws RemoteException {
16565        if (sig != Process.SIGNAL_USR1) {
16566            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16567        }
16568
16569        synchronized (this) {
16570            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16571                    != PackageManager.PERMISSION_GRANTED) {
16572                throw new SecurityException("Requires permission "
16573                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16574            }
16575
16576            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16577                ProcessRecord r = mLruProcesses.get(i);
16578                if (r.thread != null && r.persistent) {
16579                    Process.sendSignal(r.pid, sig);
16580                }
16581            }
16582        }
16583    }
16584
16585    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16586        if (proc == null || proc == mProfileProc) {
16587            proc = mProfileProc;
16588            path = mProfileFile;
16589            profileType = mProfileType;
16590            clearProfilerLocked();
16591        }
16592        if (proc == null) {
16593            return;
16594        }
16595        try {
16596            proc.thread.profilerControl(false, path, null, profileType);
16597        } catch (RemoteException e) {
16598            throw new IllegalStateException("Process disappeared");
16599        }
16600    }
16601
16602    private void clearProfilerLocked() {
16603        if (mProfileFd != null) {
16604            try {
16605                mProfileFd.close();
16606            } catch (IOException e) {
16607            }
16608        }
16609        mProfileApp = null;
16610        mProfileProc = null;
16611        mProfileFile = null;
16612        mProfileType = 0;
16613        mAutoStopProfiler = false;
16614    }
16615
16616    public boolean profileControl(String process, int userId, boolean start,
16617            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16618
16619        try {
16620            synchronized (this) {
16621                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16622                // its own permission.
16623                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16624                        != PackageManager.PERMISSION_GRANTED) {
16625                    throw new SecurityException("Requires permission "
16626                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16627                }
16628
16629                if (start && fd == null) {
16630                    throw new IllegalArgumentException("null fd");
16631                }
16632
16633                ProcessRecord proc = null;
16634                if (process != null) {
16635                    proc = findProcessLocked(process, userId, "profileControl");
16636                }
16637
16638                if (start && (proc == null || proc.thread == null)) {
16639                    throw new IllegalArgumentException("Unknown process: " + process);
16640                }
16641
16642                if (start) {
16643                    stopProfilerLocked(null, null, 0);
16644                    setProfileApp(proc.info, proc.processName, path, fd, false);
16645                    mProfileProc = proc;
16646                    mProfileType = profileType;
16647                    try {
16648                        fd = fd.dup();
16649                    } catch (IOException e) {
16650                        fd = null;
16651                    }
16652                    proc.thread.profilerControl(start, path, fd, profileType);
16653                    fd = null;
16654                    mProfileFd = null;
16655                } else {
16656                    stopProfilerLocked(proc, path, profileType);
16657                    if (fd != null) {
16658                        try {
16659                            fd.close();
16660                        } catch (IOException e) {
16661                        }
16662                    }
16663                }
16664
16665                return true;
16666            }
16667        } catch (RemoteException e) {
16668            throw new IllegalStateException("Process disappeared");
16669        } finally {
16670            if (fd != null) {
16671                try {
16672                    fd.close();
16673                } catch (IOException e) {
16674                }
16675            }
16676        }
16677    }
16678
16679    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16680        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16681                userId, true, true, callName, null);
16682        ProcessRecord proc = null;
16683        try {
16684            int pid = Integer.parseInt(process);
16685            synchronized (mPidsSelfLocked) {
16686                proc = mPidsSelfLocked.get(pid);
16687            }
16688        } catch (NumberFormatException e) {
16689        }
16690
16691        if (proc == null) {
16692            ArrayMap<String, SparseArray<ProcessRecord>> all
16693                    = mProcessNames.getMap();
16694            SparseArray<ProcessRecord> procs = all.get(process);
16695            if (procs != null && procs.size() > 0) {
16696                proc = procs.valueAt(0);
16697                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16698                    for (int i=1; i<procs.size(); i++) {
16699                        ProcessRecord thisProc = procs.valueAt(i);
16700                        if (thisProc.userId == userId) {
16701                            proc = thisProc;
16702                            break;
16703                        }
16704                    }
16705                }
16706            }
16707        }
16708
16709        return proc;
16710    }
16711
16712    public boolean dumpHeap(String process, int userId, boolean managed,
16713            String path, ParcelFileDescriptor fd) throws RemoteException {
16714
16715        try {
16716            synchronized (this) {
16717                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16718                // its own permission (same as profileControl).
16719                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16720                        != PackageManager.PERMISSION_GRANTED) {
16721                    throw new SecurityException("Requires permission "
16722                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16723                }
16724
16725                if (fd == null) {
16726                    throw new IllegalArgumentException("null fd");
16727                }
16728
16729                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16730                if (proc == null || proc.thread == null) {
16731                    throw new IllegalArgumentException("Unknown process: " + process);
16732                }
16733
16734                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16735                if (!isDebuggable) {
16736                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16737                        throw new SecurityException("Process not debuggable: " + proc);
16738                    }
16739                }
16740
16741                proc.thread.dumpHeap(managed, path, fd);
16742                fd = null;
16743                return true;
16744            }
16745        } catch (RemoteException e) {
16746            throw new IllegalStateException("Process disappeared");
16747        } finally {
16748            if (fd != null) {
16749                try {
16750                    fd.close();
16751                } catch (IOException e) {
16752                }
16753            }
16754        }
16755    }
16756
16757    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16758    public void monitor() {
16759        synchronized (this) { }
16760    }
16761
16762    void onCoreSettingsChange(Bundle settings) {
16763        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16764            ProcessRecord processRecord = mLruProcesses.get(i);
16765            try {
16766                if (processRecord.thread != null) {
16767                    processRecord.thread.setCoreSettings(settings);
16768                }
16769            } catch (RemoteException re) {
16770                /* ignore */
16771            }
16772        }
16773    }
16774
16775    // Multi-user methods
16776
16777    /**
16778     * Start user, if its not already running, but don't bring it to foreground.
16779     */
16780    @Override
16781    public boolean startUserInBackground(final int userId) {
16782        return startUser(userId, /* foreground */ false);
16783    }
16784
16785    /**
16786     * Refreshes the list of users related to the current user when either a
16787     * user switch happens or when a new related user is started in the
16788     * background.
16789     */
16790    private void updateCurrentProfileIdsLocked() {
16791        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16792                mCurrentUserId, false /* enabledOnly */);
16793        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16794        for (int i = 0; i < currentProfileIds.length; i++) {
16795            currentProfileIds[i] = profiles.get(i).id;
16796        }
16797        mCurrentProfileIds = currentProfileIds;
16798    }
16799
16800    private Set getProfileIdsLocked(int userId) {
16801        Set userIds = new HashSet<Integer>();
16802        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16803                userId, false /* enabledOnly */);
16804        for (UserInfo user : profiles) {
16805            userIds.add(Integer.valueOf(user.id));
16806        }
16807        return userIds;
16808    }
16809
16810    @Override
16811    public boolean switchUser(final int userId) {
16812        return startUser(userId, /* foregound */ true);
16813    }
16814
16815    private boolean startUser(final int userId, boolean foreground) {
16816        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16817                != PackageManager.PERMISSION_GRANTED) {
16818            String msg = "Permission Denial: switchUser() from pid="
16819                    + Binder.getCallingPid()
16820                    + ", uid=" + Binder.getCallingUid()
16821                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16822            Slog.w(TAG, msg);
16823            throw new SecurityException(msg);
16824        }
16825
16826        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16827
16828        final long ident = Binder.clearCallingIdentity();
16829        try {
16830            synchronized (this) {
16831                final int oldUserId = mCurrentUserId;
16832                if (oldUserId == userId) {
16833                    return true;
16834                }
16835
16836                mStackSupervisor.setLockTaskModeLocked(null, false);
16837
16838                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16839                if (userInfo == null) {
16840                    Slog.w(TAG, "No user info for user #" + userId);
16841                    return false;
16842                }
16843
16844                if (foreground) {
16845                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16846                            R.anim.screen_user_enter);
16847                }
16848
16849                boolean needStart = false;
16850
16851                // If the user we are switching to is not currently started, then
16852                // we need to start it now.
16853                if (mStartedUsers.get(userId) == null) {
16854                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16855                    updateStartedUserArrayLocked();
16856                    needStart = true;
16857                }
16858
16859                final Integer userIdInt = Integer.valueOf(userId);
16860                mUserLru.remove(userIdInt);
16861                mUserLru.add(userIdInt);
16862
16863                if (foreground) {
16864                    mCurrentUserId = userId;
16865                    updateCurrentProfileIdsLocked();
16866                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16867                    // Once the internal notion of the active user has switched, we lock the device
16868                    // with the option to show the user switcher on the keyguard.
16869                    mWindowManager.lockNow(null);
16870                } else {
16871                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16872                    updateCurrentProfileIdsLocked();
16873                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16874                    mUserLru.remove(currentUserIdInt);
16875                    mUserLru.add(currentUserIdInt);
16876                }
16877
16878                final UserStartedState uss = mStartedUsers.get(userId);
16879
16880                // Make sure user is in the started state.  If it is currently
16881                // stopping, we need to knock that off.
16882                if (uss.mState == UserStartedState.STATE_STOPPING) {
16883                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16884                    // so we can just fairly silently bring the user back from
16885                    // the almost-dead.
16886                    uss.mState = UserStartedState.STATE_RUNNING;
16887                    updateStartedUserArrayLocked();
16888                    needStart = true;
16889                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16890                    // This means ACTION_SHUTDOWN has been sent, so we will
16891                    // need to treat this as a new boot of the user.
16892                    uss.mState = UserStartedState.STATE_BOOTING;
16893                    updateStartedUserArrayLocked();
16894                    needStart = true;
16895                }
16896
16897                if (uss.mState == UserStartedState.STATE_BOOTING) {
16898                    // Booting up a new user, need to tell system services about it.
16899                    // Note that this is on the same handler as scheduling of broadcasts,
16900                    // which is important because it needs to go first.
16901                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16902                }
16903
16904                if (foreground) {
16905                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16906                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16907                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16908                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16909                            oldUserId, userId, uss));
16910                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16911                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16912                }
16913
16914                if (needStart) {
16915                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16916                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16917                            | Intent.FLAG_RECEIVER_FOREGROUND);
16918                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16919                    broadcastIntentLocked(null, null, intent,
16920                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16921                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16922                }
16923
16924                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16925                    if (userId != UserHandle.USER_OWNER) {
16926                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16927                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16928                        broadcastIntentLocked(null, null, intent, null,
16929                                new IIntentReceiver.Stub() {
16930                                    public void performReceive(Intent intent, int resultCode,
16931                                            String data, Bundle extras, boolean ordered,
16932                                            boolean sticky, int sendingUser) {
16933                                        userInitialized(uss, userId);
16934                                    }
16935                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16936                                true, false, MY_PID, Process.SYSTEM_UID,
16937                                userId);
16938                        uss.initializing = true;
16939                    } else {
16940                        getUserManagerLocked().makeInitialized(userInfo.id);
16941                    }
16942                }
16943
16944                if (foreground) {
16945                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16946                    if (homeInFront) {
16947                        startHomeActivityLocked(userId);
16948                    } else {
16949                        mStackSupervisor.resumeTopActivitiesLocked();
16950                    }
16951                    EventLogTags.writeAmSwitchUser(userId);
16952                    getUserManagerLocked().userForeground(userId);
16953                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16954                } else {
16955                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16956                }
16957
16958                if (needStart) {
16959                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16960                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16961                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16962                    broadcastIntentLocked(null, null, intent,
16963                            null, new IIntentReceiver.Stub() {
16964                                @Override
16965                                public void performReceive(Intent intent, int resultCode, String data,
16966                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16967                                        throws RemoteException {
16968                                }
16969                            }, 0, null, null,
16970                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16971                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16972                }
16973            }
16974        } finally {
16975            Binder.restoreCallingIdentity(ident);
16976        }
16977
16978        return true;
16979    }
16980
16981    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16982        long ident = Binder.clearCallingIdentity();
16983        try {
16984            Intent intent;
16985            if (oldUserId >= 0) {
16986                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16987                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16988                        | Intent.FLAG_RECEIVER_FOREGROUND);
16989                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16990                broadcastIntentLocked(null, null, intent,
16991                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16992                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16993            }
16994            if (newUserId >= 0) {
16995                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16996                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16997                        | Intent.FLAG_RECEIVER_FOREGROUND);
16998                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16999                broadcastIntentLocked(null, null, intent,
17000                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17001                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
17002                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17003                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17004                        | Intent.FLAG_RECEIVER_FOREGROUND);
17005                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17006                broadcastIntentLocked(null, null, intent,
17007                        null, null, 0, null, null,
17008                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17009                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17010            }
17011        } finally {
17012            Binder.restoreCallingIdentity(ident);
17013        }
17014    }
17015
17016    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17017            final int newUserId) {
17018        final int N = mUserSwitchObservers.beginBroadcast();
17019        if (N > 0) {
17020            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17021                int mCount = 0;
17022                @Override
17023                public void sendResult(Bundle data) throws RemoteException {
17024                    synchronized (ActivityManagerService.this) {
17025                        if (mCurUserSwitchCallback == this) {
17026                            mCount++;
17027                            if (mCount == N) {
17028                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17029                            }
17030                        }
17031                    }
17032                }
17033            };
17034            synchronized (this) {
17035                uss.switching = true;
17036                mCurUserSwitchCallback = callback;
17037            }
17038            for (int i=0; i<N; i++) {
17039                try {
17040                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17041                            newUserId, callback);
17042                } catch (RemoteException e) {
17043                }
17044            }
17045        } else {
17046            synchronized (this) {
17047                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17048            }
17049        }
17050        mUserSwitchObservers.finishBroadcast();
17051    }
17052
17053    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17054        synchronized (this) {
17055            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17056            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17057        }
17058    }
17059
17060    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17061        mCurUserSwitchCallback = null;
17062        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17063        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17064                oldUserId, newUserId, uss));
17065    }
17066
17067    void userInitialized(UserStartedState uss, int newUserId) {
17068        completeSwitchAndInitalize(uss, newUserId, true, false);
17069    }
17070
17071    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17072        completeSwitchAndInitalize(uss, newUserId, false, true);
17073    }
17074
17075    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17076            boolean clearInitializing, boolean clearSwitching) {
17077        boolean unfrozen = false;
17078        synchronized (this) {
17079            if (clearInitializing) {
17080                uss.initializing = false;
17081                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17082            }
17083            if (clearSwitching) {
17084                uss.switching = false;
17085            }
17086            if (!uss.switching && !uss.initializing) {
17087                mWindowManager.stopFreezingScreen();
17088                unfrozen = true;
17089            }
17090        }
17091        if (unfrozen) {
17092            final int N = mUserSwitchObservers.beginBroadcast();
17093            for (int i=0; i<N; i++) {
17094                try {
17095                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17096                } catch (RemoteException e) {
17097                }
17098            }
17099            mUserSwitchObservers.finishBroadcast();
17100        }
17101    }
17102
17103    void scheduleStartProfilesLocked() {
17104        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17105            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17106                    DateUtils.SECOND_IN_MILLIS);
17107        }
17108    }
17109
17110    void startProfilesLocked() {
17111        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17112        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17113                mCurrentUserId, false /* enabledOnly */);
17114        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17115        for (UserInfo user : profiles) {
17116            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17117                    && user.id != mCurrentUserId) {
17118                toStart.add(user);
17119            }
17120        }
17121        final int n = toStart.size();
17122        int i = 0;
17123        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17124            startUserInBackground(toStart.get(i).id);
17125        }
17126        if (i < n) {
17127            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17128        }
17129    }
17130
17131    void finishUserBoot(UserStartedState uss) {
17132        synchronized (this) {
17133            if (uss.mState == UserStartedState.STATE_BOOTING
17134                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17135                uss.mState = UserStartedState.STATE_RUNNING;
17136                final int userId = uss.mHandle.getIdentifier();
17137                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17138                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17139                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17140                broadcastIntentLocked(null, null, intent,
17141                        null, null, 0, null, null,
17142                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17143                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17144            }
17145        }
17146    }
17147
17148    void finishUserSwitch(UserStartedState uss) {
17149        synchronized (this) {
17150            finishUserBoot(uss);
17151
17152            startProfilesLocked();
17153
17154            int num = mUserLru.size();
17155            int i = 0;
17156            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17157                Integer oldUserId = mUserLru.get(i);
17158                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17159                if (oldUss == null) {
17160                    // Shouldn't happen, but be sane if it does.
17161                    mUserLru.remove(i);
17162                    num--;
17163                    continue;
17164                }
17165                if (oldUss.mState == UserStartedState.STATE_STOPPING
17166                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17167                    // This user is already stopping, doesn't count.
17168                    num--;
17169                    i++;
17170                    continue;
17171                }
17172                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17173                    // Owner and current can't be stopped, but count as running.
17174                    i++;
17175                    continue;
17176                }
17177                // This is a user to be stopped.
17178                stopUserLocked(oldUserId, null);
17179                num--;
17180                i++;
17181            }
17182        }
17183    }
17184
17185    @Override
17186    public int stopUser(final int userId, final IStopUserCallback callback) {
17187        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17188                != PackageManager.PERMISSION_GRANTED) {
17189            String msg = "Permission Denial: switchUser() from pid="
17190                    + Binder.getCallingPid()
17191                    + ", uid=" + Binder.getCallingUid()
17192                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17193            Slog.w(TAG, msg);
17194            throw new SecurityException(msg);
17195        }
17196        if (userId <= 0) {
17197            throw new IllegalArgumentException("Can't stop primary user " + userId);
17198        }
17199        synchronized (this) {
17200            return stopUserLocked(userId, callback);
17201        }
17202    }
17203
17204    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17205        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17206        if (mCurrentUserId == userId) {
17207            return ActivityManager.USER_OP_IS_CURRENT;
17208        }
17209
17210        final UserStartedState uss = mStartedUsers.get(userId);
17211        if (uss == null) {
17212            // User is not started, nothing to do...  but we do need to
17213            // callback if requested.
17214            if (callback != null) {
17215                mHandler.post(new Runnable() {
17216                    @Override
17217                    public void run() {
17218                        try {
17219                            callback.userStopped(userId);
17220                        } catch (RemoteException e) {
17221                        }
17222                    }
17223                });
17224            }
17225            return ActivityManager.USER_OP_SUCCESS;
17226        }
17227
17228        if (callback != null) {
17229            uss.mStopCallbacks.add(callback);
17230        }
17231
17232        if (uss.mState != UserStartedState.STATE_STOPPING
17233                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17234            uss.mState = UserStartedState.STATE_STOPPING;
17235            updateStartedUserArrayLocked();
17236
17237            long ident = Binder.clearCallingIdentity();
17238            try {
17239                // We are going to broadcast ACTION_USER_STOPPING and then
17240                // once that is done send a final ACTION_SHUTDOWN and then
17241                // stop the user.
17242                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17243                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17244                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17245                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17246                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17247                // This is the result receiver for the final shutdown broadcast.
17248                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17249                    @Override
17250                    public void performReceive(Intent intent, int resultCode, String data,
17251                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17252                        finishUserStop(uss);
17253                    }
17254                };
17255                // This is the result receiver for the initial stopping broadcast.
17256                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17257                    @Override
17258                    public void performReceive(Intent intent, int resultCode, String data,
17259                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17260                        // On to the next.
17261                        synchronized (ActivityManagerService.this) {
17262                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17263                                // Whoops, we are being started back up.  Abort, abort!
17264                                return;
17265                            }
17266                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17267                        }
17268                        mSystemServiceManager.stopUser(userId);
17269                        broadcastIntentLocked(null, null, shutdownIntent,
17270                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17271                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17272                    }
17273                };
17274                // Kick things off.
17275                broadcastIntentLocked(null, null, stoppingIntent,
17276                        null, stoppingReceiver, 0, null, null,
17277                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17278                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17279            } finally {
17280                Binder.restoreCallingIdentity(ident);
17281            }
17282        }
17283
17284        return ActivityManager.USER_OP_SUCCESS;
17285    }
17286
17287    void finishUserStop(UserStartedState uss) {
17288        final int userId = uss.mHandle.getIdentifier();
17289        boolean stopped;
17290        ArrayList<IStopUserCallback> callbacks;
17291        synchronized (this) {
17292            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17293            if (mStartedUsers.get(userId) != uss) {
17294                stopped = false;
17295            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17296                stopped = false;
17297            } else {
17298                stopped = true;
17299                // User can no longer run.
17300                mStartedUsers.remove(userId);
17301                mUserLru.remove(Integer.valueOf(userId));
17302                updateStartedUserArrayLocked();
17303
17304                // Clean up all state and processes associated with the user.
17305                // Kill all the processes for the user.
17306                forceStopUserLocked(userId, "finish user");
17307            }
17308        }
17309
17310        for (int i=0; i<callbacks.size(); i++) {
17311            try {
17312                if (stopped) callbacks.get(i).userStopped(userId);
17313                else callbacks.get(i).userStopAborted(userId);
17314            } catch (RemoteException e) {
17315            }
17316        }
17317
17318        if (stopped) {
17319            mSystemServiceManager.cleanupUser(userId);
17320            synchronized (this) {
17321                mStackSupervisor.removeUserLocked(userId);
17322            }
17323        }
17324    }
17325
17326    @Override
17327    public UserInfo getCurrentUser() {
17328        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17329                != PackageManager.PERMISSION_GRANTED) && (
17330                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17331                != PackageManager.PERMISSION_GRANTED)) {
17332            String msg = "Permission Denial: getCurrentUser() from pid="
17333                    + Binder.getCallingPid()
17334                    + ", uid=" + Binder.getCallingUid()
17335                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17336            Slog.w(TAG, msg);
17337            throw new SecurityException(msg);
17338        }
17339        synchronized (this) {
17340            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17341        }
17342    }
17343
17344    int getCurrentUserIdLocked() {
17345        return mCurrentUserId;
17346    }
17347
17348    @Override
17349    public boolean isUserRunning(int userId, boolean orStopped) {
17350        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17351                != PackageManager.PERMISSION_GRANTED) {
17352            String msg = "Permission Denial: isUserRunning() from pid="
17353                    + Binder.getCallingPid()
17354                    + ", uid=" + Binder.getCallingUid()
17355                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17356            Slog.w(TAG, msg);
17357            throw new SecurityException(msg);
17358        }
17359        synchronized (this) {
17360            return isUserRunningLocked(userId, orStopped);
17361        }
17362    }
17363
17364    boolean isUserRunningLocked(int userId, boolean orStopped) {
17365        UserStartedState state = mStartedUsers.get(userId);
17366        if (state == null) {
17367            return false;
17368        }
17369        if (orStopped) {
17370            return true;
17371        }
17372        return state.mState != UserStartedState.STATE_STOPPING
17373                && state.mState != UserStartedState.STATE_SHUTDOWN;
17374    }
17375
17376    @Override
17377    public int[] getRunningUserIds() {
17378        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17379                != PackageManager.PERMISSION_GRANTED) {
17380            String msg = "Permission Denial: isUserRunning() from pid="
17381                    + Binder.getCallingPid()
17382                    + ", uid=" + Binder.getCallingUid()
17383                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17384            Slog.w(TAG, msg);
17385            throw new SecurityException(msg);
17386        }
17387        synchronized (this) {
17388            return mStartedUserArray;
17389        }
17390    }
17391
17392    private void updateStartedUserArrayLocked() {
17393        int num = 0;
17394        for (int i=0; i<mStartedUsers.size();  i++) {
17395            UserStartedState uss = mStartedUsers.valueAt(i);
17396            // This list does not include stopping users.
17397            if (uss.mState != UserStartedState.STATE_STOPPING
17398                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17399                num++;
17400            }
17401        }
17402        mStartedUserArray = new int[num];
17403        num = 0;
17404        for (int i=0; i<mStartedUsers.size();  i++) {
17405            UserStartedState uss = mStartedUsers.valueAt(i);
17406            if (uss.mState != UserStartedState.STATE_STOPPING
17407                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17408                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17409                num++;
17410            }
17411        }
17412    }
17413
17414    @Override
17415    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17416        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17417                != PackageManager.PERMISSION_GRANTED) {
17418            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17419                    + Binder.getCallingPid()
17420                    + ", uid=" + Binder.getCallingUid()
17421                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17422            Slog.w(TAG, msg);
17423            throw new SecurityException(msg);
17424        }
17425
17426        mUserSwitchObservers.register(observer);
17427    }
17428
17429    @Override
17430    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17431        mUserSwitchObservers.unregister(observer);
17432    }
17433
17434    private boolean userExists(int userId) {
17435        if (userId == 0) {
17436            return true;
17437        }
17438        UserManagerService ums = getUserManagerLocked();
17439        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17440    }
17441
17442    int[] getUsersLocked() {
17443        UserManagerService ums = getUserManagerLocked();
17444        return ums != null ? ums.getUserIds() : new int[] { 0 };
17445    }
17446
17447    UserManagerService getUserManagerLocked() {
17448        if (mUserManager == null) {
17449            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17450            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17451        }
17452        return mUserManager;
17453    }
17454
17455    private int applyUserId(int uid, int userId) {
17456        return UserHandle.getUid(userId, uid);
17457    }
17458
17459    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17460        if (info == null) return null;
17461        ApplicationInfo newInfo = new ApplicationInfo(info);
17462        newInfo.uid = applyUserId(info.uid, userId);
17463        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17464                + info.packageName;
17465        return newInfo;
17466    }
17467
17468    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17469        if (aInfo == null
17470                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17471            return aInfo;
17472        }
17473
17474        ActivityInfo info = new ActivityInfo(aInfo);
17475        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17476        return info;
17477    }
17478
17479    private final class LocalService extends ActivityManagerInternal {
17480        @Override
17481        public void goingToSleep() {
17482            ActivityManagerService.this.goingToSleep();
17483        }
17484
17485        @Override
17486        public void wakingUp() {
17487            ActivityManagerService.this.wakingUp();
17488        }
17489    }
17490
17491    /**
17492     * An implementation of IAppTask, that allows an app to manage its own tasks via
17493     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17494     * only the process that calls getAppTasks() can call the AppTask methods.
17495     */
17496    class AppTaskImpl extends IAppTask.Stub {
17497        private int mTaskId;
17498        private int mCallingUid;
17499
17500        public AppTaskImpl(int taskId, int callingUid) {
17501            mTaskId = taskId;
17502            mCallingUid = callingUid;
17503        }
17504
17505        @Override
17506        public void finishAndRemoveTask() {
17507            // Ensure that we are called from the same process that created this AppTask
17508            if (mCallingUid != Binder.getCallingUid()) {
17509                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17510                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17511                return;
17512            }
17513
17514            synchronized (ActivityManagerService.this) {
17515                long origId = Binder.clearCallingIdentity();
17516                try {
17517                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17518                    if (tr != null) {
17519                        // Only kill the process if we are not a new document
17520                        int flags = tr.getBaseIntent().getFlags();
17521                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17522                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17523                        removeTaskByIdLocked(mTaskId,
17524                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17525                    }
17526                } finally {
17527                    Binder.restoreCallingIdentity(origId);
17528                }
17529            }
17530        }
17531
17532        @Override
17533        public ActivityManager.RecentTaskInfo getTaskInfo() {
17534            // Ensure that we are called from the same process that created this AppTask
17535            if (mCallingUid != Binder.getCallingUid()) {
17536                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17537                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17538                return null;
17539            }
17540
17541            synchronized (ActivityManagerService.this) {
17542                long origId = Binder.clearCallingIdentity();
17543                try {
17544                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17545                    if (tr != null) {
17546                        return createRecentTaskInfoFromTaskRecord(tr);
17547                    }
17548                } finally {
17549                    Binder.restoreCallingIdentity(origId);
17550                }
17551                return null;
17552            }
17553        }
17554    }
17555}
17556