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