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