ActivityManagerService.java revision a8f569c10a423ced5be7e019c3df2bca11b052f5
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 boolean willActivityBeVisible(IBinder token) {
3896        synchronized(this) {
3897            ActivityStack stack = ActivityRecord.getStackLocked(token);
3898            if (stack != null) {
3899                return stack.willActivityBeVisibleLocked(token);
3900            }
3901            return false;
3902        }
3903    }
3904
3905    @Override
3906    public void overridePendingTransition(IBinder token, String packageName,
3907            int enterAnim, int exitAnim) {
3908        synchronized(this) {
3909            ActivityRecord self = ActivityRecord.isInStackLocked(token);
3910            if (self == null) {
3911                return;
3912            }
3913
3914            final long origId = Binder.clearCallingIdentity();
3915
3916            if (self.state == ActivityState.RESUMED
3917                    || self.state == ActivityState.PAUSING) {
3918                mWindowManager.overridePendingAppTransition(packageName,
3919                        enterAnim, exitAnim, null);
3920            }
3921
3922            Binder.restoreCallingIdentity(origId);
3923        }
3924    }
3925
3926    /**
3927     * Main function for removing an existing process from the activity manager
3928     * as a result of that process going away.  Clears out all connections
3929     * to the process.
3930     */
3931    private final void handleAppDiedLocked(ProcessRecord app,
3932            boolean restarting, boolean allowRestart) {
3933        int pid = app.pid;
3934        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
3935        if (!restarting) {
3936            removeLruProcessLocked(app);
3937            if (pid > 0) {
3938                ProcessList.remove(pid);
3939            }
3940        }
3941
3942        if (mProfileProc == app) {
3943            clearProfilerLocked();
3944        }
3945
3946        // Remove this application's activities from active lists.
3947        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
3948
3949        app.activities.clear();
3950
3951        if (app.instrumentationClass != null) {
3952            Slog.w(TAG, "Crash of app " + app.processName
3953                  + " running instrumentation " + app.instrumentationClass);
3954            Bundle info = new Bundle();
3955            info.putString("shortMsg", "Process crashed.");
3956            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
3957        }
3958
3959        if (!restarting) {
3960            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
3961                // If there was nothing to resume, and we are not already
3962                // restarting this process, but there is a visible activity that
3963                // is hosted by the process...  then make sure all visible
3964                // activities are running, taking care of restarting this
3965                // process.
3966                if (hasVisibleActivities) {
3967                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
3968                }
3969            }
3970        }
3971    }
3972
3973    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3974        IBinder threadBinder = thread.asBinder();
3975        // Find the application record.
3976        for (int i=mLruProcesses.size()-1; i>=0; i--) {
3977            ProcessRecord rec = mLruProcesses.get(i);
3978            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3979                return i;
3980            }
3981        }
3982        return -1;
3983    }
3984
3985    final ProcessRecord getRecordForAppLocked(
3986            IApplicationThread thread) {
3987        if (thread == null) {
3988            return null;
3989        }
3990
3991        int appIndex = getLRURecordIndexForAppLocked(thread);
3992        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
3993    }
3994
3995    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
3996        // If there are no longer any background processes running,
3997        // and the app that died was not running instrumentation,
3998        // then tell everyone we are now low on memory.
3999        boolean haveBg = false;
4000        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4001            ProcessRecord rec = mLruProcesses.get(i);
4002            if (rec.thread != null
4003                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4004                haveBg = true;
4005                break;
4006            }
4007        }
4008
4009        if (!haveBg) {
4010            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4011            if (doReport) {
4012                long now = SystemClock.uptimeMillis();
4013                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4014                    doReport = false;
4015                } else {
4016                    mLastMemUsageReportTime = now;
4017                }
4018            }
4019            final ArrayList<ProcessMemInfo> memInfos
4020                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4021            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4022            long now = SystemClock.uptimeMillis();
4023            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4024                ProcessRecord rec = mLruProcesses.get(i);
4025                if (rec == dyingProc || rec.thread == null) {
4026                    continue;
4027                }
4028                if (doReport) {
4029                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4030                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4031                }
4032                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4033                    // The low memory report is overriding any current
4034                    // state for a GC request.  Make sure to do
4035                    // heavy/important/visible/foreground processes first.
4036                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4037                        rec.lastRequestedGc = 0;
4038                    } else {
4039                        rec.lastRequestedGc = rec.lastLowMemory;
4040                    }
4041                    rec.reportLowMemory = true;
4042                    rec.lastLowMemory = now;
4043                    mProcessesToGc.remove(rec);
4044                    addProcessToGcListLocked(rec);
4045                }
4046            }
4047            if (doReport) {
4048                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4049                mHandler.sendMessage(msg);
4050            }
4051            scheduleAppGcsLocked();
4052        }
4053    }
4054
4055    final void appDiedLocked(ProcessRecord app, int pid,
4056            IApplicationThread thread) {
4057
4058        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4059        synchronized (stats) {
4060            stats.noteProcessDiedLocked(app.info.uid, pid);
4061        }
4062
4063        // Clean up already done if the process has been re-started.
4064        if (app.pid == pid && app.thread != null &&
4065                app.thread.asBinder() == thread.asBinder()) {
4066            boolean doLowMem = app.instrumentationClass == null;
4067            boolean doOomAdj = doLowMem;
4068            if (!app.killedByAm) {
4069                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4070                        + ") has died.");
4071                mAllowLowerMemLevel = true;
4072            } else {
4073                // Note that we always want to do oom adj to update our state with the
4074                // new number of procs.
4075                mAllowLowerMemLevel = false;
4076                doLowMem = false;
4077            }
4078            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4079            if (DEBUG_CLEANUP) Slog.v(
4080                TAG, "Dying app: " + app + ", pid: " + pid
4081                + ", thread: " + thread.asBinder());
4082            handleAppDiedLocked(app, false, true);
4083
4084            if (doOomAdj) {
4085                updateOomAdjLocked();
4086            }
4087            if (doLowMem) {
4088                doLowMemReportIfNeededLocked(app);
4089            }
4090        } else if (app.pid != pid) {
4091            // A new process has already been started.
4092            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4093                    + ") has died and restarted (pid " + app.pid + ").");
4094            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4095        } else if (DEBUG_PROCESSES) {
4096            Slog.d(TAG, "Received spurious death notification for thread "
4097                    + thread.asBinder());
4098        }
4099    }
4100
4101    /**
4102     * If a stack trace dump file is configured, dump process stack traces.
4103     * @param clearTraces causes the dump file to be erased prior to the new
4104     *    traces being written, if true; when false, the new traces will be
4105     *    appended to any existing file content.
4106     * @param firstPids of dalvik VM processes to dump stack traces for first
4107     * @param lastPids of dalvik VM processes to dump stack traces for last
4108     * @param nativeProcs optional list of native process names to dump stack crawls
4109     * @return file containing stack traces, or null if no dump file is configured
4110     */
4111    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4112            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4113        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4114        if (tracesPath == null || tracesPath.length() == 0) {
4115            return null;
4116        }
4117
4118        File tracesFile = new File(tracesPath);
4119        try {
4120            File tracesDir = tracesFile.getParentFile();
4121            if (!tracesDir.exists()) {
4122                tracesFile.mkdirs();
4123                if (!SELinux.restorecon(tracesDir)) {
4124                    return null;
4125                }
4126            }
4127            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4128
4129            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4130            tracesFile.createNewFile();
4131            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4132        } catch (IOException e) {
4133            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4134            return null;
4135        }
4136
4137        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4138        return tracesFile;
4139    }
4140
4141    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4142            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4143        // Use a FileObserver to detect when traces finish writing.
4144        // The order of traces is considered important to maintain for legibility.
4145        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4146            @Override
4147            public synchronized void onEvent(int event, String path) { notify(); }
4148        };
4149
4150        try {
4151            observer.startWatching();
4152
4153            // First collect all of the stacks of the most important pids.
4154            if (firstPids != null) {
4155                try {
4156                    int num = firstPids.size();
4157                    for (int i = 0; i < num; i++) {
4158                        synchronized (observer) {
4159                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4160                            observer.wait(200);  // Wait for write-close, give up after 200msec
4161                        }
4162                    }
4163                } catch (InterruptedException e) {
4164                    Log.wtf(TAG, e);
4165                }
4166            }
4167
4168            // Next collect the stacks of the native pids
4169            if (nativeProcs != null) {
4170                int[] pids = Process.getPidsForCommands(nativeProcs);
4171                if (pids != null) {
4172                    for (int pid : pids) {
4173                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4174                    }
4175                }
4176            }
4177
4178            // Lastly, measure CPU usage.
4179            if (processCpuTracker != null) {
4180                processCpuTracker.init();
4181                System.gc();
4182                processCpuTracker.update();
4183                try {
4184                    synchronized (processCpuTracker) {
4185                        processCpuTracker.wait(500); // measure over 1/2 second.
4186                    }
4187                } catch (InterruptedException e) {
4188                }
4189                processCpuTracker.update();
4190
4191                // We'll take the stack crawls of just the top apps using CPU.
4192                final int N = processCpuTracker.countWorkingStats();
4193                int numProcs = 0;
4194                for (int i=0; i<N && numProcs<5; i++) {
4195                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4196                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4197                        numProcs++;
4198                        try {
4199                            synchronized (observer) {
4200                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4201                                observer.wait(200);  // Wait for write-close, give up after 200msec
4202                            }
4203                        } catch (InterruptedException e) {
4204                            Log.wtf(TAG, e);
4205                        }
4206
4207                    }
4208                }
4209            }
4210        } finally {
4211            observer.stopWatching();
4212        }
4213    }
4214
4215    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4216        if (true || IS_USER_BUILD) {
4217            return;
4218        }
4219        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4220        if (tracesPath == null || tracesPath.length() == 0) {
4221            return;
4222        }
4223
4224        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4225        StrictMode.allowThreadDiskWrites();
4226        try {
4227            final File tracesFile = new File(tracesPath);
4228            final File tracesDir = tracesFile.getParentFile();
4229            final File tracesTmp = new File(tracesDir, "__tmp__");
4230            try {
4231                if (!tracesDir.exists()) {
4232                    tracesFile.mkdirs();
4233                    if (!SELinux.restorecon(tracesDir.getPath())) {
4234                        return;
4235                    }
4236                }
4237                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4238
4239                if (tracesFile.exists()) {
4240                    tracesTmp.delete();
4241                    tracesFile.renameTo(tracesTmp);
4242                }
4243                StringBuilder sb = new StringBuilder();
4244                Time tobj = new Time();
4245                tobj.set(System.currentTimeMillis());
4246                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4247                sb.append(": ");
4248                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4249                sb.append(" since ");
4250                sb.append(msg);
4251                FileOutputStream fos = new FileOutputStream(tracesFile);
4252                fos.write(sb.toString().getBytes());
4253                if (app == null) {
4254                    fos.write("\n*** No application process!".getBytes());
4255                }
4256                fos.close();
4257                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4258            } catch (IOException e) {
4259                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4260                return;
4261            }
4262
4263            if (app != null) {
4264                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4265                firstPids.add(app.pid);
4266                dumpStackTraces(tracesPath, firstPids, null, null, null);
4267            }
4268
4269            File lastTracesFile = null;
4270            File curTracesFile = null;
4271            for (int i=9; i>=0; i--) {
4272                String name = String.format(Locale.US, "slow%02d.txt", i);
4273                curTracesFile = new File(tracesDir, name);
4274                if (curTracesFile.exists()) {
4275                    if (lastTracesFile != null) {
4276                        curTracesFile.renameTo(lastTracesFile);
4277                    } else {
4278                        curTracesFile.delete();
4279                    }
4280                }
4281                lastTracesFile = curTracesFile;
4282            }
4283            tracesFile.renameTo(curTracesFile);
4284            if (tracesTmp.exists()) {
4285                tracesTmp.renameTo(tracesFile);
4286            }
4287        } finally {
4288            StrictMode.setThreadPolicy(oldPolicy);
4289        }
4290    }
4291
4292    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4293            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4294        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4295        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4296
4297        if (mController != null) {
4298            try {
4299                // 0 == continue, -1 = kill process immediately
4300                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4301                if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
4302            } catch (RemoteException e) {
4303                mController = null;
4304                Watchdog.getInstance().setActivityController(null);
4305            }
4306        }
4307
4308        long anrTime = SystemClock.uptimeMillis();
4309        if (MONITOR_CPU_USAGE) {
4310            updateCpuStatsNow();
4311        }
4312
4313        synchronized (this) {
4314            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4315            if (mShuttingDown) {
4316                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4317                return;
4318            } else if (app.notResponding) {
4319                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4320                return;
4321            } else if (app.crashing) {
4322                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4323                return;
4324            }
4325
4326            // In case we come through here for the same app before completing
4327            // this one, mark as anring now so we will bail out.
4328            app.notResponding = true;
4329
4330            // Log the ANR to the event log.
4331            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4332                    app.processName, app.info.flags, annotation);
4333
4334            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4335            firstPids.add(app.pid);
4336
4337            int parentPid = app.pid;
4338            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4339            if (parentPid != app.pid) firstPids.add(parentPid);
4340
4341            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4342
4343            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4344                ProcessRecord r = mLruProcesses.get(i);
4345                if (r != null && r.thread != null) {
4346                    int pid = r.pid;
4347                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4348                        if (r.persistent) {
4349                            firstPids.add(pid);
4350                        } else {
4351                            lastPids.put(pid, Boolean.TRUE);
4352                        }
4353                    }
4354                }
4355            }
4356        }
4357
4358        // Log the ANR to the main log.
4359        StringBuilder info = new StringBuilder();
4360        info.setLength(0);
4361        info.append("ANR in ").append(app.processName);
4362        if (activity != null && activity.shortComponentName != null) {
4363            info.append(" (").append(activity.shortComponentName).append(")");
4364        }
4365        info.append("\n");
4366        info.append("PID: ").append(app.pid).append("\n");
4367        if (annotation != null) {
4368            info.append("Reason: ").append(annotation).append("\n");
4369        }
4370        if (parent != null && parent != activity) {
4371            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4372        }
4373
4374        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4375
4376        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4377                NATIVE_STACKS_OF_INTEREST);
4378
4379        String cpuInfo = null;
4380        if (MONITOR_CPU_USAGE) {
4381            updateCpuStatsNow();
4382            synchronized (mProcessCpuThread) {
4383                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4384            }
4385            info.append(processCpuTracker.printCurrentLoad());
4386            info.append(cpuInfo);
4387        }
4388
4389        info.append(processCpuTracker.printCurrentState(anrTime));
4390
4391        Slog.e(TAG, info.toString());
4392        if (tracesFile == null) {
4393            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4394            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4395        }
4396
4397        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4398                cpuInfo, tracesFile, null);
4399
4400        if (mController != null) {
4401            try {
4402                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4403                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4404                if (res != 0) {
4405                    if (res < 0 && app.pid != MY_PID) {
4406                        Process.killProcess(app.pid);
4407                    } else {
4408                        synchronized (this) {
4409                            mServices.scheduleServiceTimeoutLocked(app);
4410                        }
4411                    }
4412                    return;
4413                }
4414            } catch (RemoteException e) {
4415                mController = null;
4416                Watchdog.getInstance().setActivityController(null);
4417            }
4418        }
4419
4420        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4421        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4422                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4423
4424        synchronized (this) {
4425            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4426                killUnneededProcessLocked(app, "background ANR");
4427                return;
4428            }
4429
4430            // Set the app's notResponding state, and look up the errorReportReceiver
4431            makeAppNotRespondingLocked(app,
4432                    activity != null ? activity.shortComponentName : null,
4433                    annotation != null ? "ANR " + annotation : "ANR",
4434                    info.toString());
4435
4436            // Bring up the infamous App Not Responding dialog
4437            Message msg = Message.obtain();
4438            HashMap<String, Object> map = new HashMap<String, Object>();
4439            msg.what = SHOW_NOT_RESPONDING_MSG;
4440            msg.obj = map;
4441            msg.arg1 = aboveSystem ? 1 : 0;
4442            map.put("app", app);
4443            if (activity != null) {
4444                map.put("activity", activity);
4445            }
4446
4447            mHandler.sendMessage(msg);
4448        }
4449    }
4450
4451    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4452        if (!mLaunchWarningShown) {
4453            mLaunchWarningShown = true;
4454            mHandler.post(new Runnable() {
4455                @Override
4456                public void run() {
4457                    synchronized (ActivityManagerService.this) {
4458                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4459                        d.show();
4460                        mHandler.postDelayed(new Runnable() {
4461                            @Override
4462                            public void run() {
4463                                synchronized (ActivityManagerService.this) {
4464                                    d.dismiss();
4465                                    mLaunchWarningShown = false;
4466                                }
4467                            }
4468                        }, 4000);
4469                    }
4470                }
4471            });
4472        }
4473    }
4474
4475    @Override
4476    public boolean clearApplicationUserData(final String packageName,
4477            final IPackageDataObserver observer, int userId) {
4478        enforceNotIsolatedCaller("clearApplicationUserData");
4479        int uid = Binder.getCallingUid();
4480        int pid = Binder.getCallingPid();
4481        userId = handleIncomingUser(pid, uid,
4482                userId, false, true, "clearApplicationUserData", null);
4483        long callingId = Binder.clearCallingIdentity();
4484        try {
4485            IPackageManager pm = AppGlobals.getPackageManager();
4486            int pkgUid = -1;
4487            synchronized(this) {
4488                try {
4489                    pkgUid = pm.getPackageUid(packageName, userId);
4490                } catch (RemoteException e) {
4491                }
4492                if (pkgUid == -1) {
4493                    Slog.w(TAG, "Invalid packageName: " + packageName);
4494                    if (observer != null) {
4495                        try {
4496                            observer.onRemoveCompleted(packageName, false);
4497                        } catch (RemoteException e) {
4498                            Slog.i(TAG, "Observer no longer exists.");
4499                        }
4500                    }
4501                    return false;
4502                }
4503                if (uid == pkgUid || checkComponentPermission(
4504                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4505                        pid, uid, -1, true)
4506                        == PackageManager.PERMISSION_GRANTED) {
4507                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4508                } else {
4509                    throw new SecurityException("PID " + pid + " does not have permission "
4510                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4511                                    + " of package " + packageName);
4512                }
4513            }
4514
4515            try {
4516                // Clear application user data
4517                pm.clearApplicationUserData(packageName, observer, userId);
4518
4519                // Remove all permissions granted from/to this package
4520                removeUriPermissionsForPackageLocked(packageName, userId, true);
4521
4522                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4523                        Uri.fromParts("package", packageName, null));
4524                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4525                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4526                        null, null, 0, null, null, null, false, false, userId);
4527            } catch (RemoteException e) {
4528            }
4529        } finally {
4530            Binder.restoreCallingIdentity(callingId);
4531        }
4532        return true;
4533    }
4534
4535    @Override
4536    public void killBackgroundProcesses(final String packageName, int userId) {
4537        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4538                != PackageManager.PERMISSION_GRANTED &&
4539                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4540                        != PackageManager.PERMISSION_GRANTED) {
4541            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4542                    + Binder.getCallingPid()
4543                    + ", uid=" + Binder.getCallingUid()
4544                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4545            Slog.w(TAG, msg);
4546            throw new SecurityException(msg);
4547        }
4548
4549        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4550                userId, true, true, "killBackgroundProcesses", null);
4551        long callingId = Binder.clearCallingIdentity();
4552        try {
4553            IPackageManager pm = AppGlobals.getPackageManager();
4554            synchronized(this) {
4555                int appId = -1;
4556                try {
4557                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4558                } catch (RemoteException e) {
4559                }
4560                if (appId == -1) {
4561                    Slog.w(TAG, "Invalid packageName: " + packageName);
4562                    return;
4563                }
4564                killPackageProcessesLocked(packageName, appId, userId,
4565                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4566            }
4567        } finally {
4568            Binder.restoreCallingIdentity(callingId);
4569        }
4570    }
4571
4572    @Override
4573    public void killAllBackgroundProcesses() {
4574        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4575                != PackageManager.PERMISSION_GRANTED) {
4576            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4577                    + Binder.getCallingPid()
4578                    + ", uid=" + Binder.getCallingUid()
4579                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4580            Slog.w(TAG, msg);
4581            throw new SecurityException(msg);
4582        }
4583
4584        long callingId = Binder.clearCallingIdentity();
4585        try {
4586            synchronized(this) {
4587                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4588                final int NP = mProcessNames.getMap().size();
4589                for (int ip=0; ip<NP; ip++) {
4590                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4591                    final int NA = apps.size();
4592                    for (int ia=0; ia<NA; ia++) {
4593                        ProcessRecord app = apps.valueAt(ia);
4594                        if (app.persistent) {
4595                            // we don't kill persistent processes
4596                            continue;
4597                        }
4598                        if (app.removed) {
4599                            procs.add(app);
4600                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4601                            app.removed = true;
4602                            procs.add(app);
4603                        }
4604                    }
4605                }
4606
4607                int N = procs.size();
4608                for (int i=0; i<N; i++) {
4609                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4610                }
4611                mAllowLowerMemLevel = true;
4612                updateOomAdjLocked();
4613                doLowMemReportIfNeededLocked(null);
4614            }
4615        } finally {
4616            Binder.restoreCallingIdentity(callingId);
4617        }
4618    }
4619
4620    @Override
4621    public void forceStopPackage(final String packageName, int userId) {
4622        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4623                != PackageManager.PERMISSION_GRANTED) {
4624            String msg = "Permission Denial: forceStopPackage() from pid="
4625                    + Binder.getCallingPid()
4626                    + ", uid=" + Binder.getCallingUid()
4627                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4628            Slog.w(TAG, msg);
4629            throw new SecurityException(msg);
4630        }
4631        final int callingPid = Binder.getCallingPid();
4632        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4633                userId, true, true, "forceStopPackage", null);
4634        long callingId = Binder.clearCallingIdentity();
4635        try {
4636            IPackageManager pm = AppGlobals.getPackageManager();
4637            synchronized(this) {
4638                int[] users = userId == UserHandle.USER_ALL
4639                        ? getUsersLocked() : new int[] { userId };
4640                for (int user : users) {
4641                    int pkgUid = -1;
4642                    try {
4643                        pkgUid = pm.getPackageUid(packageName, user);
4644                    } catch (RemoteException e) {
4645                    }
4646                    if (pkgUid == -1) {
4647                        Slog.w(TAG, "Invalid packageName: " + packageName);
4648                        continue;
4649                    }
4650                    try {
4651                        pm.setPackageStoppedState(packageName, true, user);
4652                    } catch (RemoteException e) {
4653                    } catch (IllegalArgumentException e) {
4654                        Slog.w(TAG, "Failed trying to unstop package "
4655                                + packageName + ": " + e);
4656                    }
4657                    if (isUserRunningLocked(user, false)) {
4658                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4659                    }
4660                }
4661            }
4662        } finally {
4663            Binder.restoreCallingIdentity(callingId);
4664        }
4665    }
4666
4667    /*
4668     * The pkg name and app id have to be specified.
4669     */
4670    @Override
4671    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4672        if (pkg == null) {
4673            return;
4674        }
4675        // Make sure the uid is valid.
4676        if (appid < 0) {
4677            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4678            return;
4679        }
4680        int callerUid = Binder.getCallingUid();
4681        // Only the system server can kill an application
4682        if (callerUid == Process.SYSTEM_UID) {
4683            // Post an aysnc message to kill the application
4684            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4685            msg.arg1 = appid;
4686            msg.arg2 = 0;
4687            Bundle bundle = new Bundle();
4688            bundle.putString("pkg", pkg);
4689            bundle.putString("reason", reason);
4690            msg.obj = bundle;
4691            mHandler.sendMessage(msg);
4692        } else {
4693            throw new SecurityException(callerUid + " cannot kill pkg: " +
4694                    pkg);
4695        }
4696    }
4697
4698    @Override
4699    public void closeSystemDialogs(String reason) {
4700        enforceNotIsolatedCaller("closeSystemDialogs");
4701
4702        final int pid = Binder.getCallingPid();
4703        final int uid = Binder.getCallingUid();
4704        final long origId = Binder.clearCallingIdentity();
4705        try {
4706            synchronized (this) {
4707                // Only allow this from foreground processes, so that background
4708                // applications can't abuse it to prevent system UI from being shown.
4709                if (uid >= Process.FIRST_APPLICATION_UID) {
4710                    ProcessRecord proc;
4711                    synchronized (mPidsSelfLocked) {
4712                        proc = mPidsSelfLocked.get(pid);
4713                    }
4714                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4715                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4716                                + " from background process " + proc);
4717                        return;
4718                    }
4719                }
4720                closeSystemDialogsLocked(reason);
4721            }
4722        } finally {
4723            Binder.restoreCallingIdentity(origId);
4724        }
4725    }
4726
4727    void closeSystemDialogsLocked(String reason) {
4728        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4729        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4730                | Intent.FLAG_RECEIVER_FOREGROUND);
4731        if (reason != null) {
4732            intent.putExtra("reason", reason);
4733        }
4734        mWindowManager.closeSystemDialogs(reason);
4735
4736        mStackSupervisor.closeSystemDialogsLocked();
4737
4738        broadcastIntentLocked(null, null, intent, null,
4739                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4740                Process.SYSTEM_UID, UserHandle.USER_ALL);
4741    }
4742
4743    @Override
4744    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4745        enforceNotIsolatedCaller("getProcessMemoryInfo");
4746        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4747        for (int i=pids.length-1; i>=0; i--) {
4748            ProcessRecord proc;
4749            int oomAdj;
4750            synchronized (this) {
4751                synchronized (mPidsSelfLocked) {
4752                    proc = mPidsSelfLocked.get(pids[i]);
4753                    oomAdj = proc != null ? proc.setAdj : 0;
4754                }
4755            }
4756            infos[i] = new Debug.MemoryInfo();
4757            Debug.getMemoryInfo(pids[i], infos[i]);
4758            if (proc != null) {
4759                synchronized (this) {
4760                    if (proc.thread != null && proc.setAdj == oomAdj) {
4761                        // Record this for posterity if the process has been stable.
4762                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4763                                infos[i].getTotalUss(), false, proc.pkgList);
4764                    }
4765                }
4766            }
4767        }
4768        return infos;
4769    }
4770
4771    @Override
4772    public long[] getProcessPss(int[] pids) {
4773        enforceNotIsolatedCaller("getProcessPss");
4774        long[] pss = new long[pids.length];
4775        for (int i=pids.length-1; i>=0; i--) {
4776            ProcessRecord proc;
4777            int oomAdj;
4778            synchronized (this) {
4779                synchronized (mPidsSelfLocked) {
4780                    proc = mPidsSelfLocked.get(pids[i]);
4781                    oomAdj = proc != null ? proc.setAdj : 0;
4782                }
4783            }
4784            long[] tmpUss = new long[1];
4785            pss[i] = Debug.getPss(pids[i], tmpUss);
4786            if (proc != null) {
4787                synchronized (this) {
4788                    if (proc.thread != null && proc.setAdj == oomAdj) {
4789                        // Record this for posterity if the process has been stable.
4790                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4791                    }
4792                }
4793            }
4794        }
4795        return pss;
4796    }
4797
4798    @Override
4799    public void killApplicationProcess(String processName, int uid) {
4800        if (processName == null) {
4801            return;
4802        }
4803
4804        int callerUid = Binder.getCallingUid();
4805        // Only the system server can kill an application
4806        if (callerUid == Process.SYSTEM_UID) {
4807            synchronized (this) {
4808                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4809                if (app != null && app.thread != null) {
4810                    try {
4811                        app.thread.scheduleSuicide();
4812                    } catch (RemoteException e) {
4813                        // If the other end already died, then our work here is done.
4814                    }
4815                } else {
4816                    Slog.w(TAG, "Process/uid not found attempting kill of "
4817                            + processName + " / " + uid);
4818                }
4819            }
4820        } else {
4821            throw new SecurityException(callerUid + " cannot kill app process: " +
4822                    processName);
4823        }
4824    }
4825
4826    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4827        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4828                false, true, false, false, UserHandle.getUserId(uid), reason);
4829        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4830                Uri.fromParts("package", packageName, null));
4831        if (!mProcessesReady) {
4832            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4833                    | Intent.FLAG_RECEIVER_FOREGROUND);
4834        }
4835        intent.putExtra(Intent.EXTRA_UID, uid);
4836        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4837        broadcastIntentLocked(null, null, intent,
4838                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4839                false, false,
4840                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4841    }
4842
4843    private void forceStopUserLocked(int userId, String reason) {
4844        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4845        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4846        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4847                | Intent.FLAG_RECEIVER_FOREGROUND);
4848        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4849        broadcastIntentLocked(null, null, intent,
4850                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4851                false, false,
4852                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
4853    }
4854
4855    private final boolean killPackageProcessesLocked(String packageName, int appId,
4856            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
4857            boolean doit, boolean evenPersistent, String reason) {
4858        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4859
4860        // Remove all processes this package may have touched: all with the
4861        // same UID (except for the system or root user), and all whose name
4862        // matches the package name.
4863        final String procNamePrefix = packageName != null ? (packageName + ":") : null;
4864        final int NP = mProcessNames.getMap().size();
4865        for (int ip=0; ip<NP; ip++) {
4866            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4867            final int NA = apps.size();
4868            for (int ia=0; ia<NA; ia++) {
4869                ProcessRecord app = apps.valueAt(ia);
4870                if (app.persistent && !evenPersistent) {
4871                    // we don't kill persistent processes
4872                    continue;
4873                }
4874                if (app.removed) {
4875                    if (doit) {
4876                        procs.add(app);
4877                    }
4878                    continue;
4879                }
4880
4881                // Skip process if it doesn't meet our oom adj requirement.
4882                if (app.setAdj < minOomAdj) {
4883                    continue;
4884                }
4885
4886                // If no package is specified, we call all processes under the
4887                // give user id.
4888                if (packageName == null) {
4889                    if (app.userId != userId) {
4890                        continue;
4891                    }
4892                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
4893                        continue;
4894                    }
4895                // Package has been specified, we want to hit all processes
4896                // that match it.  We need to qualify this by the processes
4897                // that are running under the specified app and user ID.
4898                } else {
4899                    if (UserHandle.getAppId(app.uid) != appId) {
4900                        continue;
4901                    }
4902                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
4903                        continue;
4904                    }
4905                    if (!app.pkgList.containsKey(packageName)) {
4906                        continue;
4907                    }
4908                }
4909
4910                // Process has passed all conditions, kill it!
4911                if (!doit) {
4912                    return true;
4913                }
4914                app.removed = true;
4915                procs.add(app);
4916            }
4917        }
4918
4919        int N = procs.size();
4920        for (int i=0; i<N; i++) {
4921            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
4922        }
4923        updateOomAdjLocked();
4924        return N > 0;
4925    }
4926
4927    private final boolean forceStopPackageLocked(String name, int appId,
4928            boolean callerWillRestart, boolean purgeCache, boolean doit,
4929            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
4930        int i;
4931        int N;
4932
4933        if (userId == UserHandle.USER_ALL && name == null) {
4934            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
4935        }
4936
4937        if (appId < 0 && name != null) {
4938            try {
4939                appId = UserHandle.getAppId(
4940                        AppGlobals.getPackageManager().getPackageUid(name, 0));
4941            } catch (RemoteException e) {
4942            }
4943        }
4944
4945        if (doit) {
4946            if (name != null) {
4947                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
4948                        + " user=" + userId + ": " + reason);
4949            } else {
4950                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
4951            }
4952
4953            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
4954            for (int ip=pmap.size()-1; ip>=0; ip--) {
4955                SparseArray<Long> ba = pmap.valueAt(ip);
4956                for (i=ba.size()-1; i>=0; i--) {
4957                    boolean remove = false;
4958                    final int entUid = ba.keyAt(i);
4959                    if (name != null) {
4960                        if (userId == UserHandle.USER_ALL) {
4961                            if (UserHandle.getAppId(entUid) == appId) {
4962                                remove = true;
4963                            }
4964                        } else {
4965                            if (entUid == UserHandle.getUid(userId, appId)) {
4966                                remove = true;
4967                            }
4968                        }
4969                    } else if (UserHandle.getUserId(entUid) == userId) {
4970                        remove = true;
4971                    }
4972                    if (remove) {
4973                        ba.removeAt(i);
4974                    }
4975                }
4976                if (ba.size() == 0) {
4977                    pmap.removeAt(ip);
4978                }
4979            }
4980        }
4981
4982        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
4983                -100, callerWillRestart, true, doit, evenPersistent,
4984                name == null ? ("stop user " + userId) : ("stop " + name));
4985
4986        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
4987            if (!doit) {
4988                return true;
4989            }
4990            didSomething = true;
4991        }
4992
4993        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
4994            if (!doit) {
4995                return true;
4996            }
4997            didSomething = true;
4998        }
4999
5000        if (name == null) {
5001            // Remove all sticky broadcasts from this user.
5002            mStickyBroadcasts.remove(userId);
5003        }
5004
5005        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5006        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5007                userId, providers)) {
5008            if (!doit) {
5009                return true;
5010            }
5011            didSomething = true;
5012        }
5013        N = providers.size();
5014        for (i=0; i<N; i++) {
5015            removeDyingProviderLocked(null, providers.get(i), true);
5016        }
5017
5018        // Remove transient permissions granted from/to this package/user
5019        removeUriPermissionsForPackageLocked(name, userId, false);
5020
5021        if (name == null || uninstalling) {
5022            // Remove pending intents.  For now we only do this when force
5023            // stopping users, because we have some problems when doing this
5024            // for packages -- app widgets are not currently cleaned up for
5025            // such packages, so they can be left with bad pending intents.
5026            if (mIntentSenderRecords.size() > 0) {
5027                Iterator<WeakReference<PendingIntentRecord>> it
5028                        = mIntentSenderRecords.values().iterator();
5029                while (it.hasNext()) {
5030                    WeakReference<PendingIntentRecord> wpir = it.next();
5031                    if (wpir == null) {
5032                        it.remove();
5033                        continue;
5034                    }
5035                    PendingIntentRecord pir = wpir.get();
5036                    if (pir == null) {
5037                        it.remove();
5038                        continue;
5039                    }
5040                    if (name == null) {
5041                        // Stopping user, remove all objects for the user.
5042                        if (pir.key.userId != userId) {
5043                            // Not the same user, skip it.
5044                            continue;
5045                        }
5046                    } else {
5047                        if (UserHandle.getAppId(pir.uid) != appId) {
5048                            // Different app id, skip it.
5049                            continue;
5050                        }
5051                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5052                            // Different user, skip it.
5053                            continue;
5054                        }
5055                        if (!pir.key.packageName.equals(name)) {
5056                            // Different package, skip it.
5057                            continue;
5058                        }
5059                    }
5060                    if (!doit) {
5061                        return true;
5062                    }
5063                    didSomething = true;
5064                    it.remove();
5065                    pir.canceled = true;
5066                    if (pir.key.activity != null) {
5067                        pir.key.activity.pendingResults.remove(pir.ref);
5068                    }
5069                }
5070            }
5071        }
5072
5073        if (doit) {
5074            if (purgeCache && name != null) {
5075                AttributeCache ac = AttributeCache.instance();
5076                if (ac != null) {
5077                    ac.removePackage(name);
5078                }
5079            }
5080            if (mBooted) {
5081                mStackSupervisor.resumeTopActivitiesLocked();
5082                mStackSupervisor.scheduleIdleLocked();
5083            }
5084        }
5085
5086        return didSomething;
5087    }
5088
5089    private final boolean removeProcessLocked(ProcessRecord app,
5090            boolean callerWillRestart, boolean allowRestart, String reason) {
5091        final String name = app.processName;
5092        final int uid = app.uid;
5093        if (DEBUG_PROCESSES) Slog.d(
5094            TAG, "Force removing proc " + app.toShortString() + " (" + name
5095            + "/" + uid + ")");
5096
5097        mProcessNames.remove(name, uid);
5098        mIsolatedProcesses.remove(app.uid);
5099        if (mHeavyWeightProcess == app) {
5100            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5101                    mHeavyWeightProcess.userId, 0));
5102            mHeavyWeightProcess = null;
5103        }
5104        boolean needRestart = false;
5105        if (app.pid > 0 && app.pid != MY_PID) {
5106            int pid = app.pid;
5107            synchronized (mPidsSelfLocked) {
5108                mPidsSelfLocked.remove(pid);
5109                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5110            }
5111            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5112                    app.processName, app.info.uid);
5113            if (app.isolated) {
5114                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5115            }
5116            killUnneededProcessLocked(app, reason);
5117            handleAppDiedLocked(app, true, allowRestart);
5118            removeLruProcessLocked(app);
5119
5120            if (app.persistent && !app.isolated) {
5121                if (!callerWillRestart) {
5122                    addAppLocked(app.info, false, null /* ABI override */);
5123                } else {
5124                    needRestart = true;
5125                }
5126            }
5127        } else {
5128            mRemovedProcesses.add(app);
5129        }
5130
5131        return needRestart;
5132    }
5133
5134    private final void processStartTimedOutLocked(ProcessRecord app) {
5135        final int pid = app.pid;
5136        boolean gone = false;
5137        synchronized (mPidsSelfLocked) {
5138            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5139            if (knownApp != null && knownApp.thread == null) {
5140                mPidsSelfLocked.remove(pid);
5141                gone = true;
5142            }
5143        }
5144
5145        if (gone) {
5146            Slog.w(TAG, "Process " + app + " failed to attach");
5147            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5148                    pid, app.uid, app.processName);
5149            mProcessNames.remove(app.processName, app.uid);
5150            mIsolatedProcesses.remove(app.uid);
5151            if (mHeavyWeightProcess == app) {
5152                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5153                        mHeavyWeightProcess.userId, 0));
5154                mHeavyWeightProcess = null;
5155            }
5156            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
5157                    app.processName, app.info.uid);
5158            if (app.isolated) {
5159                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5160            }
5161            // Take care of any launching providers waiting for this process.
5162            checkAppInLaunchingProvidersLocked(app, true);
5163            // Take care of any services that are waiting for the process.
5164            mServices.processStartTimedOutLocked(app);
5165            killUnneededProcessLocked(app, "start timeout");
5166            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5167                Slog.w(TAG, "Unattached app died before backup, skipping");
5168                try {
5169                    IBackupManager bm = IBackupManager.Stub.asInterface(
5170                            ServiceManager.getService(Context.BACKUP_SERVICE));
5171                    bm.agentDisconnected(app.info.packageName);
5172                } catch (RemoteException e) {
5173                    // Can't happen; the backup manager is local
5174                }
5175            }
5176            if (isPendingBroadcastProcessLocked(pid)) {
5177                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5178                skipPendingBroadcastLocked(pid);
5179            }
5180        } else {
5181            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5182        }
5183    }
5184
5185    private final boolean attachApplicationLocked(IApplicationThread thread,
5186            int pid) {
5187
5188        // Find the application record that is being attached...  either via
5189        // the pid if we are running in multiple processes, or just pull the
5190        // next app record if we are emulating process with anonymous threads.
5191        ProcessRecord app;
5192        if (pid != MY_PID && pid >= 0) {
5193            synchronized (mPidsSelfLocked) {
5194                app = mPidsSelfLocked.get(pid);
5195            }
5196        } else {
5197            app = null;
5198        }
5199
5200        if (app == null) {
5201            Slog.w(TAG, "No pending application record for pid " + pid
5202                    + " (IApplicationThread " + thread + "); dropping process");
5203            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5204            if (pid > 0 && pid != MY_PID) {
5205                Process.killProcessQuiet(pid);
5206            } else {
5207                try {
5208                    thread.scheduleExit();
5209                } catch (Exception e) {
5210                    // Ignore exceptions.
5211                }
5212            }
5213            return false;
5214        }
5215
5216        // If this application record is still attached to a previous
5217        // process, clean it up now.
5218        if (app.thread != null) {
5219            handleAppDiedLocked(app, true, true);
5220        }
5221
5222        // Tell the process all about itself.
5223
5224        if (localLOGV) Slog.v(
5225                TAG, "Binding process pid " + pid + " to record " + app);
5226
5227        final String processName = app.processName;
5228        try {
5229            AppDeathRecipient adr = new AppDeathRecipient(
5230                    app, pid, thread);
5231            thread.asBinder().linkToDeath(adr, 0);
5232            app.deathRecipient = adr;
5233        } catch (RemoteException e) {
5234            app.resetPackageList(mProcessStats);
5235            startProcessLocked(app, "link fail", processName, null /* ABI override */);
5236            return false;
5237        }
5238
5239        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5240
5241        app.makeActive(thread, mProcessStats);
5242        app.curAdj = app.setAdj = -100;
5243        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5244        app.forcingToForeground = null;
5245        updateProcessForegroundLocked(app, false, false);
5246        app.hasShownUi = false;
5247        app.debugging = false;
5248        app.cached = false;
5249
5250        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5251
5252        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5253        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5254
5255        if (!normalMode) {
5256            Slog.i(TAG, "Launching preboot mode app: " + app);
5257        }
5258
5259        if (localLOGV) Slog.v(
5260            TAG, "New app record " + app
5261            + " thread=" + thread.asBinder() + " pid=" + pid);
5262        try {
5263            int testMode = IApplicationThread.DEBUG_OFF;
5264            if (mDebugApp != null && mDebugApp.equals(processName)) {
5265                testMode = mWaitForDebugger
5266                    ? IApplicationThread.DEBUG_WAIT
5267                    : IApplicationThread.DEBUG_ON;
5268                app.debugging = true;
5269                if (mDebugTransient) {
5270                    mDebugApp = mOrigDebugApp;
5271                    mWaitForDebugger = mOrigWaitForDebugger;
5272                }
5273            }
5274            String profileFile = app.instrumentationProfileFile;
5275            ParcelFileDescriptor profileFd = null;
5276            boolean profileAutoStop = false;
5277            if (mProfileApp != null && mProfileApp.equals(processName)) {
5278                mProfileProc = app;
5279                profileFile = mProfileFile;
5280                profileFd = mProfileFd;
5281                profileAutoStop = mAutoStopProfiler;
5282            }
5283            boolean enableOpenGlTrace = false;
5284            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5285                enableOpenGlTrace = true;
5286                mOpenGlTraceApp = null;
5287            }
5288
5289            // If the app is being launched for restore or full backup, set it up specially
5290            boolean isRestrictedBackupMode = false;
5291            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5292                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5293                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5294                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5295            }
5296
5297            ensurePackageDexOpt(app.instrumentationInfo != null
5298                    ? app.instrumentationInfo.packageName
5299                    : app.info.packageName);
5300            if (app.instrumentationClass != null) {
5301                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5302            }
5303            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5304                    + processName + " with config " + mConfiguration);
5305            ApplicationInfo appInfo = app.instrumentationInfo != null
5306                    ? app.instrumentationInfo : app.info;
5307            app.compat = compatibilityInfoForPackageLocked(appInfo);
5308            if (profileFd != null) {
5309                profileFd = profileFd.dup();
5310            }
5311            thread.bindApplication(processName, appInfo, providers,
5312                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5313                    app.instrumentationArguments, app.instrumentationWatcher,
5314                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5315                    isRestrictedBackupMode || !normalMode, app.persistent,
5316                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5317                    mCoreSettingsObserver.getCoreSettingsLocked());
5318            updateLruProcessLocked(app, false, null);
5319            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5320        } catch (Exception e) {
5321            // todo: Yikes!  What should we do?  For now we will try to
5322            // start another process, but that could easily get us in
5323            // an infinite loop of restarting processes...
5324            Slog.w(TAG, "Exception thrown during bind!", e);
5325
5326            app.resetPackageList(mProcessStats);
5327            app.unlinkDeathRecipient();
5328            startProcessLocked(app, "bind fail", processName, null /* ABI override */);
5329            return false;
5330        }
5331
5332        // Remove this record from the list of starting applications.
5333        mPersistentStartingProcesses.remove(app);
5334        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5335                "Attach application locked removing on hold: " + app);
5336        mProcessesOnHold.remove(app);
5337
5338        boolean badApp = false;
5339        boolean didSomething = false;
5340
5341        // See if the top visible activity is waiting to run in this process...
5342        if (normalMode) {
5343            try {
5344                if (mStackSupervisor.attachApplicationLocked(app)) {
5345                    didSomething = true;
5346                }
5347            } catch (Exception e) {
5348                badApp = true;
5349            }
5350        }
5351
5352        // Find any services that should be running in this process...
5353        if (!badApp) {
5354            try {
5355                didSomething |= mServices.attachApplicationLocked(app, processName);
5356            } catch (Exception e) {
5357                badApp = true;
5358            }
5359        }
5360
5361        // Check if a next-broadcast receiver is in this process...
5362        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5363            try {
5364                didSomething |= sendPendingBroadcastsLocked(app);
5365            } catch (Exception e) {
5366                // If the app died trying to launch the receiver we declare it 'bad'
5367                badApp = true;
5368            }
5369        }
5370
5371        // Check whether the next backup agent is in this process...
5372        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5373            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5374            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5375            try {
5376                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5377                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5378                        mBackupTarget.backupMode);
5379            } catch (Exception e) {
5380                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5381                e.printStackTrace();
5382            }
5383        }
5384
5385        if (badApp) {
5386            // todo: Also need to kill application to deal with all
5387            // kinds of exceptions.
5388            handleAppDiedLocked(app, false, true);
5389            return false;
5390        }
5391
5392        if (!didSomething) {
5393            updateOomAdjLocked();
5394        }
5395
5396        return true;
5397    }
5398
5399    @Override
5400    public final void attachApplication(IApplicationThread thread) {
5401        synchronized (this) {
5402            int callingPid = Binder.getCallingPid();
5403            final long origId = Binder.clearCallingIdentity();
5404            attachApplicationLocked(thread, callingPid);
5405            Binder.restoreCallingIdentity(origId);
5406        }
5407    }
5408
5409    @Override
5410    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5411        final long origId = Binder.clearCallingIdentity();
5412        synchronized (this) {
5413            ActivityStack stack = ActivityRecord.getStackLocked(token);
5414            if (stack != null) {
5415                ActivityRecord r =
5416                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5417                if (stopProfiling) {
5418                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5419                        try {
5420                            mProfileFd.close();
5421                        } catch (IOException e) {
5422                        }
5423                        clearProfilerLocked();
5424                    }
5425                }
5426            }
5427        }
5428        Binder.restoreCallingIdentity(origId);
5429    }
5430
5431    void enableScreenAfterBoot() {
5432        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5433                SystemClock.uptimeMillis());
5434        mWindowManager.enableScreenAfterBoot();
5435
5436        synchronized (this) {
5437            updateEventDispatchingLocked();
5438        }
5439    }
5440
5441    @Override
5442    public void showBootMessage(final CharSequence msg, final boolean always) {
5443        enforceNotIsolatedCaller("showBootMessage");
5444        mWindowManager.showBootMessage(msg, always);
5445    }
5446
5447    @Override
5448    public void dismissKeyguardOnNextActivity() {
5449        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5450        final long token = Binder.clearCallingIdentity();
5451        try {
5452            synchronized (this) {
5453                if (DEBUG_LOCKSCREEN) logLockScreen("");
5454                if (mLockScreenShown) {
5455                    mLockScreenShown = false;
5456                    comeOutOfSleepIfNeededLocked();
5457                }
5458                mStackSupervisor.setDismissKeyguard(true);
5459            }
5460        } finally {
5461            Binder.restoreCallingIdentity(token);
5462        }
5463    }
5464
5465    final void finishBooting() {
5466        // Register receivers to handle package update events
5467        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5468
5469        synchronized (this) {
5470            // Ensure that any processes we had put on hold are now started
5471            // up.
5472            final int NP = mProcessesOnHold.size();
5473            if (NP > 0) {
5474                ArrayList<ProcessRecord> procs =
5475                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5476                for (int ip=0; ip<NP; ip++) {
5477                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5478                            + procs.get(ip));
5479                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */);
5480                }
5481            }
5482
5483            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5484                // Start looking for apps that are abusing wake locks.
5485                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5486                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5487                // Tell anyone interested that we are done booting!
5488                SystemProperties.set("sys.boot_completed", "1");
5489                SystemProperties.set("dev.bootcomplete", "1");
5490                for (int i=0; i<mStartedUsers.size(); i++) {
5491                    UserStartedState uss = mStartedUsers.valueAt(i);
5492                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5493                        uss.mState = UserStartedState.STATE_RUNNING;
5494                        final int userId = mStartedUsers.keyAt(i);
5495                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5496                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5497                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5498                        broadcastIntentLocked(null, null, intent, null,
5499                                new IIntentReceiver.Stub() {
5500                                    @Override
5501                                    public void performReceive(Intent intent, int resultCode,
5502                                            String data, Bundle extras, boolean ordered,
5503                                            boolean sticky, int sendingUser) {
5504                                        synchronized (ActivityManagerService.this) {
5505                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5506                                                    true, false);
5507                                        }
5508                                    }
5509                                },
5510                                0, null, null,
5511                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5512                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5513                                userId);
5514                    }
5515                }
5516                scheduleStartProfilesLocked();
5517            }
5518        }
5519    }
5520
5521    final void ensureBootCompleted() {
5522        boolean booting;
5523        boolean enableScreen;
5524        synchronized (this) {
5525            booting = mBooting;
5526            mBooting = false;
5527            enableScreen = !mBooted;
5528            mBooted = true;
5529        }
5530
5531        if (booting) {
5532            finishBooting();
5533        }
5534
5535        if (enableScreen) {
5536            enableScreenAfterBoot();
5537        }
5538    }
5539
5540    @Override
5541    public final void activityResumed(IBinder token) {
5542        final long origId = Binder.clearCallingIdentity();
5543        synchronized(this) {
5544            ActivityStack stack = ActivityRecord.getStackLocked(token);
5545            if (stack != null) {
5546                ActivityRecord.activityResumedLocked(token);
5547            }
5548        }
5549        Binder.restoreCallingIdentity(origId);
5550    }
5551
5552    @Override
5553    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5554        final long origId = Binder.clearCallingIdentity();
5555        synchronized(this) {
5556            ActivityStack stack = ActivityRecord.getStackLocked(token);
5557            if (stack != null) {
5558                stack.activityPausedLocked(token, false, persistentState);
5559            }
5560        }
5561        Binder.restoreCallingIdentity(origId);
5562    }
5563
5564    @Override
5565    public final void activityStopped(IBinder token, Bundle icicle,
5566            PersistableBundle persistentState, CharSequence description) {
5567        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5568
5569        // Refuse possible leaked file descriptors
5570        if (icicle != null && icicle.hasFileDescriptors()) {
5571            throw new IllegalArgumentException("File descriptors passed in Bundle");
5572        }
5573
5574        final long origId = Binder.clearCallingIdentity();
5575
5576        synchronized (this) {
5577            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5578            if (r != null) {
5579                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5580            }
5581        }
5582
5583        trimApplications();
5584
5585        Binder.restoreCallingIdentity(origId);
5586    }
5587
5588    @Override
5589    public final void activityDestroyed(IBinder token) {
5590        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5591        synchronized (this) {
5592            ActivityStack stack = ActivityRecord.getStackLocked(token);
5593            if (stack != null) {
5594                stack.activityDestroyedLocked(token);
5595            }
5596        }
5597    }
5598
5599    @Override
5600    public String getCallingPackage(IBinder token) {
5601        synchronized (this) {
5602            ActivityRecord r = getCallingRecordLocked(token);
5603            return r != null ? r.info.packageName : null;
5604        }
5605    }
5606
5607    @Override
5608    public ComponentName getCallingActivity(IBinder token) {
5609        synchronized (this) {
5610            ActivityRecord r = getCallingRecordLocked(token);
5611            return r != null ? r.intent.getComponent() : null;
5612        }
5613    }
5614
5615    private ActivityRecord getCallingRecordLocked(IBinder token) {
5616        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5617        if (r == null) {
5618            return null;
5619        }
5620        return r.resultTo;
5621    }
5622
5623    @Override
5624    public ComponentName getActivityClassForToken(IBinder token) {
5625        synchronized(this) {
5626            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5627            if (r == null) {
5628                return null;
5629            }
5630            return r.intent.getComponent();
5631        }
5632    }
5633
5634    @Override
5635    public String getPackageForToken(IBinder token) {
5636        synchronized(this) {
5637            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5638            if (r == null) {
5639                return null;
5640            }
5641            return r.packageName;
5642        }
5643    }
5644
5645    @Override
5646    public IIntentSender getIntentSender(int type,
5647            String packageName, IBinder token, String resultWho,
5648            int requestCode, Intent[] intents, String[] resolvedTypes,
5649            int flags, Bundle options, int userId) {
5650        enforceNotIsolatedCaller("getIntentSender");
5651        // Refuse possible leaked file descriptors
5652        if (intents != null) {
5653            if (intents.length < 1) {
5654                throw new IllegalArgumentException("Intents array length must be >= 1");
5655            }
5656            for (int i=0; i<intents.length; i++) {
5657                Intent intent = intents[i];
5658                if (intent != null) {
5659                    if (intent.hasFileDescriptors()) {
5660                        throw new IllegalArgumentException("File descriptors passed in Intent");
5661                    }
5662                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5663                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5664                        throw new IllegalArgumentException(
5665                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5666                    }
5667                    intents[i] = new Intent(intent);
5668                }
5669            }
5670            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5671                throw new IllegalArgumentException(
5672                        "Intent array length does not match resolvedTypes length");
5673            }
5674        }
5675        if (options != null) {
5676            if (options.hasFileDescriptors()) {
5677                throw new IllegalArgumentException("File descriptors passed in options");
5678            }
5679        }
5680
5681        synchronized(this) {
5682            int callingUid = Binder.getCallingUid();
5683            int origUserId = userId;
5684            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5685                    type == ActivityManager.INTENT_SENDER_BROADCAST, false,
5686                    "getIntentSender", null);
5687            if (origUserId == UserHandle.USER_CURRENT) {
5688                // We don't want to evaluate this until the pending intent is
5689                // actually executed.  However, we do want to always do the
5690                // security checking for it above.
5691                userId = UserHandle.USER_CURRENT;
5692            }
5693            try {
5694                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5695                    int uid = AppGlobals.getPackageManager()
5696                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5697                    if (!UserHandle.isSameApp(callingUid, uid)) {
5698                        String msg = "Permission Denial: getIntentSender() from pid="
5699                            + Binder.getCallingPid()
5700                            + ", uid=" + Binder.getCallingUid()
5701                            + ", (need uid=" + uid + ")"
5702                            + " is not allowed to send as package " + packageName;
5703                        Slog.w(TAG, msg);
5704                        throw new SecurityException(msg);
5705                    }
5706                }
5707
5708                return getIntentSenderLocked(type, packageName, callingUid, userId,
5709                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5710
5711            } catch (RemoteException e) {
5712                throw new SecurityException(e);
5713            }
5714        }
5715    }
5716
5717    IIntentSender getIntentSenderLocked(int type, String packageName,
5718            int callingUid, int userId, IBinder token, String resultWho,
5719            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5720            Bundle options) {
5721        if (DEBUG_MU)
5722            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5723        ActivityRecord activity = null;
5724        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5725            activity = ActivityRecord.isInStackLocked(token);
5726            if (activity == null) {
5727                return null;
5728            }
5729            if (activity.finishing) {
5730                return null;
5731            }
5732        }
5733
5734        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5735        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5736        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5737        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5738                |PendingIntent.FLAG_UPDATE_CURRENT);
5739
5740        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5741                type, packageName, activity, resultWho,
5742                requestCode, intents, resolvedTypes, flags, options, userId);
5743        WeakReference<PendingIntentRecord> ref;
5744        ref = mIntentSenderRecords.get(key);
5745        PendingIntentRecord rec = ref != null ? ref.get() : null;
5746        if (rec != null) {
5747            if (!cancelCurrent) {
5748                if (updateCurrent) {
5749                    if (rec.key.requestIntent != null) {
5750                        rec.key.requestIntent.replaceExtras(intents != null ?
5751                                intents[intents.length - 1] : null);
5752                    }
5753                    if (intents != null) {
5754                        intents[intents.length-1] = rec.key.requestIntent;
5755                        rec.key.allIntents = intents;
5756                        rec.key.allResolvedTypes = resolvedTypes;
5757                    } else {
5758                        rec.key.allIntents = null;
5759                        rec.key.allResolvedTypes = null;
5760                    }
5761                }
5762                return rec;
5763            }
5764            rec.canceled = true;
5765            mIntentSenderRecords.remove(key);
5766        }
5767        if (noCreate) {
5768            return rec;
5769        }
5770        rec = new PendingIntentRecord(this, key, callingUid);
5771        mIntentSenderRecords.put(key, rec.ref);
5772        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5773            if (activity.pendingResults == null) {
5774                activity.pendingResults
5775                        = new HashSet<WeakReference<PendingIntentRecord>>();
5776            }
5777            activity.pendingResults.add(rec.ref);
5778        }
5779        return rec;
5780    }
5781
5782    @Override
5783    public void cancelIntentSender(IIntentSender sender) {
5784        if (!(sender instanceof PendingIntentRecord)) {
5785            return;
5786        }
5787        synchronized(this) {
5788            PendingIntentRecord rec = (PendingIntentRecord)sender;
5789            try {
5790                int uid = AppGlobals.getPackageManager()
5791                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5792                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5793                    String msg = "Permission Denial: cancelIntentSender() from pid="
5794                        + Binder.getCallingPid()
5795                        + ", uid=" + Binder.getCallingUid()
5796                        + " is not allowed to cancel packges "
5797                        + rec.key.packageName;
5798                    Slog.w(TAG, msg);
5799                    throw new SecurityException(msg);
5800                }
5801            } catch (RemoteException e) {
5802                throw new SecurityException(e);
5803            }
5804            cancelIntentSenderLocked(rec, true);
5805        }
5806    }
5807
5808    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5809        rec.canceled = true;
5810        mIntentSenderRecords.remove(rec.key);
5811        if (cleanActivity && rec.key.activity != null) {
5812            rec.key.activity.pendingResults.remove(rec.ref);
5813        }
5814    }
5815
5816    @Override
5817    public String getPackageForIntentSender(IIntentSender pendingResult) {
5818        if (!(pendingResult instanceof PendingIntentRecord)) {
5819            return null;
5820        }
5821        try {
5822            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5823            return res.key.packageName;
5824        } catch (ClassCastException e) {
5825        }
5826        return null;
5827    }
5828
5829    @Override
5830    public int getUidForIntentSender(IIntentSender sender) {
5831        if (sender instanceof PendingIntentRecord) {
5832            try {
5833                PendingIntentRecord res = (PendingIntentRecord)sender;
5834                return res.uid;
5835            } catch (ClassCastException e) {
5836            }
5837        }
5838        return -1;
5839    }
5840
5841    @Override
5842    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
5843        if (!(pendingResult instanceof PendingIntentRecord)) {
5844            return false;
5845        }
5846        try {
5847            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5848            if (res.key.allIntents == null) {
5849                return false;
5850            }
5851            for (int i=0; i<res.key.allIntents.length; i++) {
5852                Intent intent = res.key.allIntents[i];
5853                if (intent.getPackage() != null && intent.getComponent() != null) {
5854                    return false;
5855                }
5856            }
5857            return true;
5858        } catch (ClassCastException e) {
5859        }
5860        return false;
5861    }
5862
5863    @Override
5864    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
5865        if (!(pendingResult instanceof PendingIntentRecord)) {
5866            return false;
5867        }
5868        try {
5869            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5870            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
5871                return true;
5872            }
5873            return false;
5874        } catch (ClassCastException e) {
5875        }
5876        return false;
5877    }
5878
5879    @Override
5880    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
5881        if (!(pendingResult instanceof PendingIntentRecord)) {
5882            return null;
5883        }
5884        try {
5885            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5886            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
5887        } catch (ClassCastException e) {
5888        }
5889        return null;
5890    }
5891
5892    @Override
5893    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
5894        if (!(pendingResult instanceof PendingIntentRecord)) {
5895            return null;
5896        }
5897        try {
5898            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
5899            Intent intent = res.key.requestIntent;
5900            if (intent != null) {
5901                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
5902                        || res.lastTagPrefix.equals(prefix))) {
5903                    return res.lastTag;
5904                }
5905                res.lastTagPrefix = prefix;
5906                StringBuilder sb = new StringBuilder(128);
5907                if (prefix != null) {
5908                    sb.append(prefix);
5909                }
5910                if (intent.getAction() != null) {
5911                    sb.append(intent.getAction());
5912                } else if (intent.getComponent() != null) {
5913                    intent.getComponent().appendShortString(sb);
5914                } else {
5915                    sb.append("?");
5916                }
5917                return res.lastTag = sb.toString();
5918            }
5919        } catch (ClassCastException e) {
5920        }
5921        return null;
5922    }
5923
5924    @Override
5925    public void setProcessLimit(int max) {
5926        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5927                "setProcessLimit()");
5928        synchronized (this) {
5929            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
5930            mProcessLimitOverride = max;
5931        }
5932        trimApplications();
5933    }
5934
5935    @Override
5936    public int getProcessLimit() {
5937        synchronized (this) {
5938            return mProcessLimitOverride;
5939        }
5940    }
5941
5942    void foregroundTokenDied(ForegroundToken token) {
5943        synchronized (ActivityManagerService.this) {
5944            synchronized (mPidsSelfLocked) {
5945                ForegroundToken cur
5946                    = mForegroundProcesses.get(token.pid);
5947                if (cur != token) {
5948                    return;
5949                }
5950                mForegroundProcesses.remove(token.pid);
5951                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
5952                if (pr == null) {
5953                    return;
5954                }
5955                pr.forcingToForeground = null;
5956                updateProcessForegroundLocked(pr, false, false);
5957            }
5958            updateOomAdjLocked();
5959        }
5960    }
5961
5962    @Override
5963    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
5964        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
5965                "setProcessForeground()");
5966        synchronized(this) {
5967            boolean changed = false;
5968
5969            synchronized (mPidsSelfLocked) {
5970                ProcessRecord pr = mPidsSelfLocked.get(pid);
5971                if (pr == null && isForeground) {
5972                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
5973                    return;
5974                }
5975                ForegroundToken oldToken = mForegroundProcesses.get(pid);
5976                if (oldToken != null) {
5977                    oldToken.token.unlinkToDeath(oldToken, 0);
5978                    mForegroundProcesses.remove(pid);
5979                    if (pr != null) {
5980                        pr.forcingToForeground = null;
5981                    }
5982                    changed = true;
5983                }
5984                if (isForeground && token != null) {
5985                    ForegroundToken newToken = new ForegroundToken() {
5986                        @Override
5987                        public void binderDied() {
5988                            foregroundTokenDied(this);
5989                        }
5990                    };
5991                    newToken.pid = pid;
5992                    newToken.token = token;
5993                    try {
5994                        token.linkToDeath(newToken, 0);
5995                        mForegroundProcesses.put(pid, newToken);
5996                        pr.forcingToForeground = token;
5997                        changed = true;
5998                    } catch (RemoteException e) {
5999                        // If the process died while doing this, we will later
6000                        // do the cleanup with the process death link.
6001                    }
6002                }
6003            }
6004
6005            if (changed) {
6006                updateOomAdjLocked();
6007            }
6008        }
6009    }
6010
6011    // =========================================================
6012    // PERMISSIONS
6013    // =========================================================
6014
6015    static class PermissionController extends IPermissionController.Stub {
6016        ActivityManagerService mActivityManagerService;
6017        PermissionController(ActivityManagerService activityManagerService) {
6018            mActivityManagerService = activityManagerService;
6019        }
6020
6021        @Override
6022        public boolean checkPermission(String permission, int pid, int uid) {
6023            return mActivityManagerService.checkPermission(permission, pid,
6024                    uid) == PackageManager.PERMISSION_GRANTED;
6025        }
6026    }
6027
6028    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6029        @Override
6030        public int checkComponentPermission(String permission, int pid, int uid,
6031                int owningUid, boolean exported) {
6032            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6033                    owningUid, exported);
6034        }
6035
6036        @Override
6037        public Object getAMSLock() {
6038            return ActivityManagerService.this;
6039        }
6040    }
6041
6042    /**
6043     * This can be called with or without the global lock held.
6044     */
6045    int checkComponentPermission(String permission, int pid, int uid,
6046            int owningUid, boolean exported) {
6047        // We might be performing an operation on behalf of an indirect binder
6048        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6049        // client identity accordingly before proceeding.
6050        Identity tlsIdentity = sCallerIdentity.get();
6051        if (tlsIdentity != null) {
6052            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6053                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6054            uid = tlsIdentity.uid;
6055            pid = tlsIdentity.pid;
6056        }
6057
6058        if (pid == MY_PID) {
6059            return PackageManager.PERMISSION_GRANTED;
6060        }
6061
6062        return ActivityManager.checkComponentPermission(permission, uid,
6063                owningUid, exported);
6064    }
6065
6066    /**
6067     * As the only public entry point for permissions checking, this method
6068     * can enforce the semantic that requesting a check on a null global
6069     * permission is automatically denied.  (Internally a null permission
6070     * string is used when calling {@link #checkComponentPermission} in cases
6071     * when only uid-based security is needed.)
6072     *
6073     * This can be called with or without the global lock held.
6074     */
6075    @Override
6076    public int checkPermission(String permission, int pid, int uid) {
6077        if (permission == null) {
6078            return PackageManager.PERMISSION_DENIED;
6079        }
6080        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6081    }
6082
6083    /**
6084     * Binder IPC calls go through the public entry point.
6085     * This can be called with or without the global lock held.
6086     */
6087    int checkCallingPermission(String permission) {
6088        return checkPermission(permission,
6089                Binder.getCallingPid(),
6090                UserHandle.getAppId(Binder.getCallingUid()));
6091    }
6092
6093    /**
6094     * This can be called with or without the global lock held.
6095     */
6096    void enforceCallingPermission(String permission, String func) {
6097        if (checkCallingPermission(permission)
6098                == PackageManager.PERMISSION_GRANTED) {
6099            return;
6100        }
6101
6102        String msg = "Permission Denial: " + func + " from pid="
6103                + Binder.getCallingPid()
6104                + ", uid=" + Binder.getCallingUid()
6105                + " requires " + permission;
6106        Slog.w(TAG, msg);
6107        throw new SecurityException(msg);
6108    }
6109
6110    /**
6111     * Determine if UID is holding permissions required to access {@link Uri} in
6112     * the given {@link ProviderInfo}. Final permission checking is always done
6113     * in {@link ContentProvider}.
6114     */
6115    private final boolean checkHoldingPermissionsLocked(
6116            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6117        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6118                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6119        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6120            return false;
6121        }
6122        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6123    }
6124
6125    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6126            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6127        if (pi.applicationInfo.uid == uid) {
6128            return true;
6129        } else if (!pi.exported) {
6130            return false;
6131        }
6132
6133        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6134        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6135        try {
6136            // check if target holds top-level <provider> permissions
6137            if (!readMet && pi.readPermission != null && considerUidPermissions
6138                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6139                readMet = true;
6140            }
6141            if (!writeMet && pi.writePermission != null && considerUidPermissions
6142                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6143                writeMet = true;
6144            }
6145
6146            // track if unprotected read/write is allowed; any denied
6147            // <path-permission> below removes this ability
6148            boolean allowDefaultRead = pi.readPermission == null;
6149            boolean allowDefaultWrite = pi.writePermission == null;
6150
6151            // check if target holds any <path-permission> that match uri
6152            final PathPermission[] pps = pi.pathPermissions;
6153            if (pps != null) {
6154                final String path = grantUri.uri.getPath();
6155                int i = pps.length;
6156                while (i > 0 && (!readMet || !writeMet)) {
6157                    i--;
6158                    PathPermission pp = pps[i];
6159                    if (pp.match(path)) {
6160                        if (!readMet) {
6161                            final String pprperm = pp.getReadPermission();
6162                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6163                                    + pprperm + " for " + pp.getPath()
6164                                    + ": match=" + pp.match(path)
6165                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6166                            if (pprperm != null) {
6167                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6168                                        == PERMISSION_GRANTED) {
6169                                    readMet = true;
6170                                } else {
6171                                    allowDefaultRead = false;
6172                                }
6173                            }
6174                        }
6175                        if (!writeMet) {
6176                            final String ppwperm = pp.getWritePermission();
6177                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6178                                    + ppwperm + " for " + pp.getPath()
6179                                    + ": match=" + pp.match(path)
6180                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6181                            if (ppwperm != null) {
6182                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6183                                        == PERMISSION_GRANTED) {
6184                                    writeMet = true;
6185                                } else {
6186                                    allowDefaultWrite = false;
6187                                }
6188                            }
6189                        }
6190                    }
6191                }
6192            }
6193
6194            // grant unprotected <provider> read/write, if not blocked by
6195            // <path-permission> above
6196            if (allowDefaultRead) readMet = true;
6197            if (allowDefaultWrite) writeMet = true;
6198
6199        } catch (RemoteException e) {
6200            return false;
6201        }
6202
6203        return readMet && writeMet;
6204    }
6205
6206    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6207        ProviderInfo pi = null;
6208        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6209        if (cpr != null) {
6210            pi = cpr.info;
6211        } else {
6212            try {
6213                pi = AppGlobals.getPackageManager().resolveContentProvider(
6214                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6215            } catch (RemoteException ex) {
6216            }
6217        }
6218        return pi;
6219    }
6220
6221    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6222        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6223        if (targetUris != null) {
6224            return targetUris.get(grantUri);
6225        }
6226        return null;
6227    }
6228
6229    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6230            String targetPkg, int targetUid, GrantUri grantUri) {
6231        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6232        if (targetUris == null) {
6233            targetUris = Maps.newArrayMap();
6234            mGrantedUriPermissions.put(targetUid, targetUris);
6235        }
6236
6237        UriPermission perm = targetUris.get(grantUri);
6238        if (perm == null) {
6239            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6240            targetUris.put(grantUri, perm);
6241        }
6242
6243        return perm;
6244    }
6245
6246    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6247            final int modeFlags) {
6248        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6249        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6250                : UriPermission.STRENGTH_OWNED;
6251
6252        // Root gets to do everything.
6253        if (uid == 0) {
6254            return true;
6255        }
6256
6257        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6258        if (perms == null) return false;
6259
6260        // First look for exact match
6261        final UriPermission exactPerm = perms.get(grantUri);
6262        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6263            return true;
6264        }
6265
6266        // No exact match, look for prefixes
6267        final int N = perms.size();
6268        for (int i = 0; i < N; i++) {
6269            final UriPermission perm = perms.valueAt(i);
6270            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6271                    && perm.getStrength(modeFlags) >= minStrength) {
6272                return true;
6273            }
6274        }
6275
6276        return false;
6277    }
6278
6279    @Override
6280    public int checkUriPermission(Uri uri, int pid, int uid,
6281            final int modeFlags, int userId) {
6282        enforceNotIsolatedCaller("checkUriPermission");
6283
6284        // Another redirected-binder-call permissions check as in
6285        // {@link checkComponentPermission}.
6286        Identity tlsIdentity = sCallerIdentity.get();
6287        if (tlsIdentity != null) {
6288            uid = tlsIdentity.uid;
6289            pid = tlsIdentity.pid;
6290        }
6291
6292        // Our own process gets to do everything.
6293        if (pid == MY_PID) {
6294            return PackageManager.PERMISSION_GRANTED;
6295        }
6296        synchronized (this) {
6297            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6298                    ? PackageManager.PERMISSION_GRANTED
6299                    : PackageManager.PERMISSION_DENIED;
6300        }
6301    }
6302
6303    /**
6304     * Check if the targetPkg can be granted permission to access uri by
6305     * the callingUid using the given modeFlags.  Throws a security exception
6306     * if callingUid is not allowed to do this.  Returns the uid of the target
6307     * if the URI permission grant should be performed; returns -1 if it is not
6308     * needed (for example targetPkg already has permission to access the URI).
6309     * If you already know the uid of the target, you can supply it in
6310     * lastTargetUid else set that to -1.
6311     */
6312    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6313            final int modeFlags, int lastTargetUid) {
6314        if (!Intent.isAccessUriMode(modeFlags)) {
6315            return -1;
6316        }
6317
6318        if (targetPkg != null) {
6319            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6320                    "Checking grant " + targetPkg + " permission to " + grantUri);
6321        }
6322
6323        final IPackageManager pm = AppGlobals.getPackageManager();
6324
6325        // If this is not a content: uri, we can't do anything with it.
6326        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6327            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6328                    "Can't grant URI permission for non-content URI: " + grantUri);
6329            return -1;
6330        }
6331
6332        final String authority = grantUri.uri.getAuthority();
6333        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6334        if (pi == null) {
6335            Slog.w(TAG, "No content provider found for permission check: " +
6336                    grantUri.uri.toSafeString());
6337            return -1;
6338        }
6339
6340        int targetUid = lastTargetUid;
6341        if (targetUid < 0 && targetPkg != null) {
6342            try {
6343                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6344                if (targetUid < 0) {
6345                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6346                            "Can't grant URI permission no uid for: " + targetPkg);
6347                    return -1;
6348                }
6349            } catch (RemoteException ex) {
6350                return -1;
6351            }
6352        }
6353
6354        if (targetUid >= 0) {
6355            // First...  does the target actually need this permission?
6356            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6357                // No need to grant the target this permission.
6358                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6359                        "Target " + targetPkg + " already has full permission to " + grantUri);
6360                return -1;
6361            }
6362        } else {
6363            // First...  there is no target package, so can anyone access it?
6364            boolean allowed = pi.exported;
6365            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6366                if (pi.readPermission != null) {
6367                    allowed = false;
6368                }
6369            }
6370            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6371                if (pi.writePermission != null) {
6372                    allowed = false;
6373                }
6374            }
6375            if (allowed) {
6376                return -1;
6377            }
6378        }
6379
6380        /* There is a special cross user grant if:
6381         * - The target is on another user.
6382         * - Apps on the current user can access the uri without any uid permissions.
6383         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6384         * grant uri permissions.
6385         */
6386        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6387                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6388                modeFlags, false /*without considering the uid permissions*/);
6389
6390        // Second...  is the provider allowing granting of URI permissions?
6391        if (!specialCrossUserGrant) {
6392            if (!pi.grantUriPermissions) {
6393                throw new SecurityException("Provider " + pi.packageName
6394                        + "/" + pi.name
6395                        + " does not allow granting of Uri permissions (uri "
6396                        + grantUri + ")");
6397            }
6398            if (pi.uriPermissionPatterns != null) {
6399                final int N = pi.uriPermissionPatterns.length;
6400                boolean allowed = false;
6401                for (int i=0; i<N; i++) {
6402                    if (pi.uriPermissionPatterns[i] != null
6403                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6404                        allowed = true;
6405                        break;
6406                    }
6407                }
6408                if (!allowed) {
6409                    throw new SecurityException("Provider " + pi.packageName
6410                            + "/" + pi.name
6411                            + " does not allow granting of permission to path of Uri "
6412                            + grantUri);
6413                }
6414            }
6415        }
6416
6417        // Third...  does the caller itself have permission to access
6418        // this uri?
6419        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6420            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6421                // Require they hold a strong enough Uri permission
6422                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6423                    throw new SecurityException("Uid " + callingUid
6424                            + " does not have permission to uri " + grantUri);
6425                }
6426            }
6427        }
6428        return targetUid;
6429    }
6430
6431    @Override
6432    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6433            final int modeFlags, int userId) {
6434        enforceNotIsolatedCaller("checkGrantUriPermission");
6435        synchronized(this) {
6436            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6437                    new GrantUri(userId, uri, false), modeFlags, -1);
6438        }
6439    }
6440
6441    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6442            final int modeFlags, UriPermissionOwner owner) {
6443        if (!Intent.isAccessUriMode(modeFlags)) {
6444            return;
6445        }
6446
6447        // So here we are: the caller has the assumed permission
6448        // to the uri, and the target doesn't.  Let's now give this to
6449        // the target.
6450
6451        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6452                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6453
6454        final String authority = grantUri.uri.getAuthority();
6455        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6456        if (pi == null) {
6457            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6458            return;
6459        }
6460
6461        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6462            grantUri.prefix = true;
6463        }
6464        final UriPermission perm = findOrCreateUriPermissionLocked(
6465                pi.packageName, targetPkg, targetUid, grantUri);
6466        perm.grantModes(modeFlags, owner);
6467    }
6468
6469    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6470            final int modeFlags, UriPermissionOwner owner) {
6471        if (targetPkg == null) {
6472            throw new NullPointerException("targetPkg");
6473        }
6474
6475        int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6476                -1);
6477        if (targetUid < 0) {
6478            return;
6479        }
6480
6481        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6482                owner);
6483    }
6484
6485    static class NeededUriGrants extends ArrayList<GrantUri> {
6486        final String targetPkg;
6487        final int targetUid;
6488        final int flags;
6489
6490        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6491            this.targetPkg = targetPkg;
6492            this.targetUid = targetUid;
6493            this.flags = flags;
6494        }
6495    }
6496
6497    /**
6498     * Like checkGrantUriPermissionLocked, but takes an Intent.
6499     */
6500    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6501            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6502        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6503                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6504                + " clip=" + (intent != null ? intent.getClipData() : null)
6505                + " from " + intent + "; flags=0x"
6506                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6507
6508        if (targetPkg == null) {
6509            throw new NullPointerException("targetPkg");
6510        }
6511
6512        if (intent == null) {
6513            return null;
6514        }
6515        Uri data = intent.getData();
6516        ClipData clip = intent.getClipData();
6517        if (data == null && clip == null) {
6518            return null;
6519        }
6520        final IPackageManager pm = AppGlobals.getPackageManager();
6521        int targetUid;
6522        if (needed != null) {
6523            targetUid = needed.targetUid;
6524        } else {
6525            try {
6526                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6527            } catch (RemoteException ex) {
6528                return null;
6529            }
6530            if (targetUid < 0) {
6531                if (DEBUG_URI_PERMISSION) {
6532                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6533                            + " on user " + targetUserId);
6534                }
6535                return null;
6536            }
6537        }
6538        if (data != null) {
6539            GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), data);
6540            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6541                    targetUid);
6542            if (targetUid > 0) {
6543                if (needed == null) {
6544                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6545                }
6546                needed.add(grantUri);
6547            }
6548        }
6549        if (clip != null) {
6550            for (int i=0; i<clip.getItemCount(); i++) {
6551                Uri uri = clip.getItemAt(i).getUri();
6552                if (uri != null) {
6553                    GrantUri grantUri = GrantUri.resolve(UserHandle.getUserId(callingUid), uri);
6554                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6555                            targetUid);
6556                    if (targetUid > 0) {
6557                        if (needed == null) {
6558                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6559                        }
6560                        needed.add(grantUri);
6561                    }
6562                } else {
6563                    Intent clipIntent = clip.getItemAt(i).getIntent();
6564                    if (clipIntent != null) {
6565                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6566                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6567                        if (newNeeded != null) {
6568                            needed = newNeeded;
6569                        }
6570                    }
6571                }
6572            }
6573        }
6574
6575        return needed;
6576    }
6577
6578    /**
6579     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6580     */
6581    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6582            UriPermissionOwner owner) {
6583        if (needed != null) {
6584            for (int i=0; i<needed.size(); i++) {
6585                GrantUri grantUri = needed.get(i);
6586                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6587                        grantUri, needed.flags, owner);
6588            }
6589        }
6590    }
6591
6592    void grantUriPermissionFromIntentLocked(int callingUid,
6593            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6594        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6595                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6596        if (needed == null) {
6597            return;
6598        }
6599
6600        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6601    }
6602
6603    @Override
6604    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6605            final int modeFlags, int userId) {
6606        enforceNotIsolatedCaller("grantUriPermission");
6607        GrantUri grantUri = new GrantUri(userId, uri, false);
6608        synchronized(this) {
6609            final ProcessRecord r = getRecordForAppLocked(caller);
6610            if (r == null) {
6611                throw new SecurityException("Unable to find app for caller "
6612                        + caller
6613                        + " when granting permission to uri " + grantUri);
6614            }
6615            if (targetPkg == null) {
6616                throw new IllegalArgumentException("null target");
6617            }
6618            if (grantUri == null) {
6619                throw new IllegalArgumentException("null uri");
6620            }
6621
6622            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6623                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6624                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6625                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6626
6627            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null);
6628        }
6629    }
6630
6631    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6632        if (perm.modeFlags == 0) {
6633            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6634                    perm.targetUid);
6635            if (perms != null) {
6636                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6637                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6638
6639                perms.remove(perm.uri);
6640                if (perms.isEmpty()) {
6641                    mGrantedUriPermissions.remove(perm.targetUid);
6642                }
6643            }
6644        }
6645    }
6646
6647    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6648        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6649
6650        final IPackageManager pm = AppGlobals.getPackageManager();
6651        final String authority = grantUri.uri.getAuthority();
6652        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6653        if (pi == null) {
6654            Slog.w(TAG, "No content provider found for permission revoke: "
6655                    + grantUri.toSafeString());
6656            return;
6657        }
6658
6659        // Does the caller have this permission on the URI?
6660        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6661            // Right now, if you are not the original owner of the permission,
6662            // you are not allowed to revoke it.
6663            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6664                throw new SecurityException("Uid " + callingUid
6665                        + " does not have permission to uri " + grantUri);
6666            //}
6667        }
6668
6669        boolean persistChanged = false;
6670
6671        // Go through all of the permissions and remove any that match.
6672        int N = mGrantedUriPermissions.size();
6673        for (int i = 0; i < N; i++) {
6674            final int targetUid = mGrantedUriPermissions.keyAt(i);
6675            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6676
6677            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6678                final UriPermission perm = it.next();
6679                if (perm.uri.sourceUserId == grantUri.sourceUserId
6680                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6681                    if (DEBUG_URI_PERMISSION)
6682                        Slog.v(TAG,
6683                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6684                    persistChanged |= perm.revokeModes(
6685                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6686                    if (perm.modeFlags == 0) {
6687                        it.remove();
6688                    }
6689                }
6690            }
6691
6692            if (perms.isEmpty()) {
6693                mGrantedUriPermissions.remove(targetUid);
6694                N--;
6695                i--;
6696            }
6697        }
6698
6699        if (persistChanged) {
6700            schedulePersistUriGrants();
6701        }
6702    }
6703
6704    @Override
6705    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6706            int userId) {
6707        enforceNotIsolatedCaller("revokeUriPermission");
6708        synchronized(this) {
6709            final ProcessRecord r = getRecordForAppLocked(caller);
6710            if (r == null) {
6711                throw new SecurityException("Unable to find app for caller "
6712                        + caller
6713                        + " when revoking permission to uri " + uri);
6714            }
6715            if (uri == null) {
6716                Slog.w(TAG, "revokeUriPermission: null uri");
6717                return;
6718            }
6719
6720            if (!Intent.isAccessUriMode(modeFlags)) {
6721                return;
6722            }
6723
6724            final IPackageManager pm = AppGlobals.getPackageManager();
6725            final String authority = uri.getAuthority();
6726            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6727            if (pi == null) {
6728                Slog.w(TAG, "No content provider found for permission revoke: "
6729                        + uri.toSafeString());
6730                return;
6731            }
6732
6733            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6734        }
6735    }
6736
6737    /**
6738     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6739     * given package.
6740     *
6741     * @param packageName Package name to match, or {@code null} to apply to all
6742     *            packages.
6743     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6744     *            to all users.
6745     * @param persistable If persistable grants should be removed.
6746     */
6747    private void removeUriPermissionsForPackageLocked(
6748            String packageName, int userHandle, boolean persistable) {
6749        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6750            throw new IllegalArgumentException("Must narrow by either package or user");
6751        }
6752
6753        boolean persistChanged = false;
6754
6755        int N = mGrantedUriPermissions.size();
6756        for (int i = 0; i < N; i++) {
6757            final int targetUid = mGrantedUriPermissions.keyAt(i);
6758            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6759
6760            // Only inspect grants matching user
6761            if (userHandle == UserHandle.USER_ALL
6762                    || userHandle == UserHandle.getUserId(targetUid)) {
6763                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6764                    final UriPermission perm = it.next();
6765
6766                    // Only inspect grants matching package
6767                    if (packageName == null || perm.sourcePkg.equals(packageName)
6768                            || perm.targetPkg.equals(packageName)) {
6769                        persistChanged |= perm.revokeModes(
6770                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6771
6772                        // Only remove when no modes remain; any persisted grants
6773                        // will keep this alive.
6774                        if (perm.modeFlags == 0) {
6775                            it.remove();
6776                        }
6777                    }
6778                }
6779
6780                if (perms.isEmpty()) {
6781                    mGrantedUriPermissions.remove(targetUid);
6782                    N--;
6783                    i--;
6784                }
6785            }
6786        }
6787
6788        if (persistChanged) {
6789            schedulePersistUriGrants();
6790        }
6791    }
6792
6793    @Override
6794    public IBinder newUriPermissionOwner(String name) {
6795        enforceNotIsolatedCaller("newUriPermissionOwner");
6796        synchronized(this) {
6797            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6798            return owner.getExternalTokenLocked();
6799        }
6800    }
6801
6802    @Override
6803    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6804            final int modeFlags, int userId) {
6805        synchronized(this) {
6806            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6807            if (owner == null) {
6808                throw new IllegalArgumentException("Unknown owner: " + token);
6809            }
6810            if (fromUid != Binder.getCallingUid()) {
6811                if (Binder.getCallingUid() != Process.myUid()) {
6812                    // Only system code can grant URI permissions on behalf
6813                    // of other users.
6814                    throw new SecurityException("nice try");
6815                }
6816            }
6817            if (targetPkg == null) {
6818                throw new IllegalArgumentException("null target");
6819            }
6820            if (uri == null) {
6821                throw new IllegalArgumentException("null uri");
6822            }
6823
6824            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(userId, uri, false),
6825                    modeFlags, owner);
6826        }
6827    }
6828
6829    @Override
6830    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
6831        synchronized(this) {
6832            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
6833            if (owner == null) {
6834                throw new IllegalArgumentException("Unknown owner: " + token);
6835            }
6836
6837            if (uri == null) {
6838                owner.removeUriPermissionsLocked(mode);
6839            } else {
6840                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
6841            }
6842        }
6843    }
6844
6845    private void schedulePersistUriGrants() {
6846        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
6847            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
6848                    10 * DateUtils.SECOND_IN_MILLIS);
6849        }
6850    }
6851
6852    private void writeGrantedUriPermissions() {
6853        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
6854
6855        // Snapshot permissions so we can persist without lock
6856        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
6857        synchronized (this) {
6858            final int size = mGrantedUriPermissions.size();
6859            for (int i = 0; i < size; i++) {
6860                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6861                for (UriPermission perm : perms.values()) {
6862                    if (perm.persistedModeFlags != 0) {
6863                        persist.add(perm.snapshot());
6864                    }
6865                }
6866            }
6867        }
6868
6869        FileOutputStream fos = null;
6870        try {
6871            fos = mGrantFile.startWrite();
6872
6873            XmlSerializer out = new FastXmlSerializer();
6874            out.setOutput(fos, "utf-8");
6875            out.startDocument(null, true);
6876            out.startTag(null, TAG_URI_GRANTS);
6877            for (UriPermission.Snapshot perm : persist) {
6878                out.startTag(null, TAG_URI_GRANT);
6879                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
6880                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
6881                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
6882                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
6883                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
6884                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
6885                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
6886                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
6887                out.endTag(null, TAG_URI_GRANT);
6888            }
6889            out.endTag(null, TAG_URI_GRANTS);
6890            out.endDocument();
6891
6892            mGrantFile.finishWrite(fos);
6893        } catch (IOException e) {
6894            if (fos != null) {
6895                mGrantFile.failWrite(fos);
6896            }
6897        }
6898    }
6899
6900    private void readGrantedUriPermissionsLocked() {
6901        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
6902
6903        final long now = System.currentTimeMillis();
6904
6905        FileInputStream fis = null;
6906        try {
6907            fis = mGrantFile.openRead();
6908            final XmlPullParser in = Xml.newPullParser();
6909            in.setInput(fis, null);
6910
6911            int type;
6912            while ((type = in.next()) != END_DOCUMENT) {
6913                final String tag = in.getName();
6914                if (type == START_TAG) {
6915                    if (TAG_URI_GRANT.equals(tag)) {
6916                        final int sourceUserId;
6917                        final int targetUserId;
6918                        final int userHandle = readIntAttribute(in,
6919                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
6920                        if (userHandle != UserHandle.USER_NULL) {
6921                            // For backwards compatibility.
6922                            sourceUserId = userHandle;
6923                            targetUserId = userHandle;
6924                        } else {
6925                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
6926                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
6927                        }
6928                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
6929                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
6930                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
6931                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
6932                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
6933                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
6934
6935                        // Sanity check that provider still belongs to source package
6936                        final ProviderInfo pi = getProviderInfoLocked(
6937                                uri.getAuthority(), sourceUserId);
6938                        if (pi != null && sourcePkg.equals(pi.packageName)) {
6939                            int targetUid = -1;
6940                            try {
6941                                targetUid = AppGlobals.getPackageManager()
6942                                        .getPackageUid(targetPkg, targetUserId);
6943                            } catch (RemoteException e) {
6944                            }
6945                            if (targetUid != -1) {
6946                                final UriPermission perm = findOrCreateUriPermissionLocked(
6947                                        sourcePkg, targetPkg, targetUid,
6948                                        new GrantUri(sourceUserId, uri, prefix));
6949                                perm.initPersistedModes(modeFlags, createdTime);
6950                            }
6951                        } else {
6952                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
6953                                    + " but instead found " + pi);
6954                        }
6955                    }
6956                }
6957            }
6958        } catch (FileNotFoundException e) {
6959            // Missing grants is okay
6960        } catch (IOException e) {
6961            Log.wtf(TAG, "Failed reading Uri grants", e);
6962        } catch (XmlPullParserException e) {
6963            Log.wtf(TAG, "Failed reading Uri grants", e);
6964        } finally {
6965            IoUtils.closeQuietly(fis);
6966        }
6967    }
6968
6969    @Override
6970    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
6971        enforceNotIsolatedCaller("takePersistableUriPermission");
6972
6973        Preconditions.checkFlagsArgument(modeFlags,
6974                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
6975
6976        synchronized (this) {
6977            final int callingUid = Binder.getCallingUid();
6978            boolean persistChanged = false;
6979            GrantUri grantUri = new GrantUri(userId, uri, false);
6980
6981            UriPermission exactPerm = findUriPermissionLocked(callingUid,
6982                    new GrantUri(userId, uri, false));
6983            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
6984                    new GrantUri(userId, uri, true));
6985
6986            final boolean exactValid = (exactPerm != null)
6987                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
6988            final boolean prefixValid = (prefixPerm != null)
6989                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
6990
6991            if (!(exactValid || prefixValid)) {
6992                throw new SecurityException("No persistable permission grants found for UID "
6993                        + callingUid + " and Uri " + grantUri.toSafeString());
6994            }
6995
6996            if (exactValid) {
6997                persistChanged |= exactPerm.takePersistableModes(modeFlags);
6998            }
6999            if (prefixValid) {
7000                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7001            }
7002
7003            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7004
7005            if (persistChanged) {
7006                schedulePersistUriGrants();
7007            }
7008        }
7009    }
7010
7011    @Override
7012    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7013        enforceNotIsolatedCaller("releasePersistableUriPermission");
7014
7015        Preconditions.checkFlagsArgument(modeFlags,
7016                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7017
7018        synchronized (this) {
7019            final int callingUid = Binder.getCallingUid();
7020            boolean persistChanged = false;
7021
7022            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7023                    new GrantUri(userId, uri, false));
7024            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7025                    new GrantUri(userId, uri, true));
7026            if (exactPerm == null && prefixPerm == null) {
7027                throw new SecurityException("No permission grants found for UID " + callingUid
7028                        + " and Uri " + uri.toSafeString());
7029            }
7030
7031            if (exactPerm != null) {
7032                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7033                removeUriPermissionIfNeededLocked(exactPerm);
7034            }
7035            if (prefixPerm != null) {
7036                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7037                removeUriPermissionIfNeededLocked(prefixPerm);
7038            }
7039
7040            if (persistChanged) {
7041                schedulePersistUriGrants();
7042            }
7043        }
7044    }
7045
7046    /**
7047     * Prune any older {@link UriPermission} for the given UID until outstanding
7048     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7049     *
7050     * @return if any mutations occured that require persisting.
7051     */
7052    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7053        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7054        if (perms == null) return false;
7055        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7056
7057        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7058        for (UriPermission perm : perms.values()) {
7059            if (perm.persistedModeFlags != 0) {
7060                persisted.add(perm);
7061            }
7062        }
7063
7064        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7065        if (trimCount <= 0) return false;
7066
7067        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7068        for (int i = 0; i < trimCount; i++) {
7069            final UriPermission perm = persisted.get(i);
7070
7071            if (DEBUG_URI_PERMISSION) {
7072                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7073            }
7074
7075            perm.releasePersistableModes(~0);
7076            removeUriPermissionIfNeededLocked(perm);
7077        }
7078
7079        return true;
7080    }
7081
7082    @Override
7083    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7084            String packageName, boolean incoming) {
7085        enforceNotIsolatedCaller("getPersistedUriPermissions");
7086        Preconditions.checkNotNull(packageName, "packageName");
7087
7088        final int callingUid = Binder.getCallingUid();
7089        final IPackageManager pm = AppGlobals.getPackageManager();
7090        try {
7091            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7092            if (packageUid != callingUid) {
7093                throw new SecurityException(
7094                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7095            }
7096        } catch (RemoteException e) {
7097            throw new SecurityException("Failed to verify package name ownership");
7098        }
7099
7100        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7101        synchronized (this) {
7102            if (incoming) {
7103                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7104                        callingUid);
7105                if (perms == null) {
7106                    Slog.w(TAG, "No permission grants found for " + packageName);
7107                } else {
7108                    for (UriPermission perm : perms.values()) {
7109                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7110                            result.add(perm.buildPersistedPublicApiObject());
7111                        }
7112                    }
7113                }
7114            } else {
7115                final int size = mGrantedUriPermissions.size();
7116                for (int i = 0; i < size; i++) {
7117                    final ArrayMap<GrantUri, UriPermission> perms =
7118                            mGrantedUriPermissions.valueAt(i);
7119                    for (UriPermission perm : perms.values()) {
7120                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7121                            result.add(perm.buildPersistedPublicApiObject());
7122                        }
7123                    }
7124                }
7125            }
7126        }
7127        return new ParceledListSlice<android.content.UriPermission>(result);
7128    }
7129
7130    @Override
7131    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7132        synchronized (this) {
7133            ProcessRecord app =
7134                who != null ? getRecordForAppLocked(who) : null;
7135            if (app == null) return;
7136
7137            Message msg = Message.obtain();
7138            msg.what = WAIT_FOR_DEBUGGER_MSG;
7139            msg.obj = app;
7140            msg.arg1 = waiting ? 1 : 0;
7141            mHandler.sendMessage(msg);
7142        }
7143    }
7144
7145    @Override
7146    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7147        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7148        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7149        outInfo.availMem = Process.getFreeMemory();
7150        outInfo.totalMem = Process.getTotalMemory();
7151        outInfo.threshold = homeAppMem;
7152        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7153        outInfo.hiddenAppThreshold = cachedAppMem;
7154        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7155                ProcessList.SERVICE_ADJ);
7156        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7157                ProcessList.VISIBLE_APP_ADJ);
7158        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7159                ProcessList.FOREGROUND_APP_ADJ);
7160    }
7161
7162    // =========================================================
7163    // TASK MANAGEMENT
7164    // =========================================================
7165
7166    @Override
7167    public List<IAppTask> getAppTasks() {
7168        final PackageManager pm = mContext.getPackageManager();
7169        int callingUid = Binder.getCallingUid();
7170        long ident = Binder.clearCallingIdentity();
7171
7172        // Compose the list of packages for this id to test against
7173        HashSet<String> packages = new HashSet<String>();
7174        String[] uidPackages = pm.getPackagesForUid(callingUid);
7175        for (int i = 0; i < uidPackages.length; i++) {
7176            packages.add(uidPackages[i]);
7177        }
7178
7179        synchronized(this) {
7180            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7181            try {
7182                if (localLOGV) Slog.v(TAG, "getAppTasks");
7183
7184                final int N = mRecentTasks.size();
7185                for (int i = 0; i < N; i++) {
7186                    TaskRecord tr = mRecentTasks.get(i);
7187                    // Skip tasks that are not created by the caller
7188                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7189                        ActivityManager.RecentTaskInfo taskInfo =
7190                                createRecentTaskInfoFromTaskRecord(tr);
7191                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7192                        list.add(taskImpl);
7193                    }
7194                }
7195            } finally {
7196                Binder.restoreCallingIdentity(ident);
7197            }
7198            return list;
7199        }
7200    }
7201
7202    @Override
7203    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7204        final int callingUid = Binder.getCallingUid();
7205        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7206
7207        synchronized(this) {
7208            if (localLOGV) Slog.v(
7209                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7210
7211            final boolean allowed = checkCallingPermission(
7212                    android.Manifest.permission.GET_TASKS)
7213                    == PackageManager.PERMISSION_GRANTED;
7214            if (!allowed) {
7215                Slog.w(TAG, "getTasks: caller " + callingUid
7216                        + " does not hold GET_TASKS; limiting output");
7217            }
7218
7219            // TODO: Improve with MRU list from all ActivityStacks.
7220            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7221        }
7222
7223        return list;
7224    }
7225
7226    TaskRecord getMostRecentTask() {
7227        return mRecentTasks.get(0);
7228    }
7229
7230    /**
7231     * Creates a new RecentTaskInfo from a TaskRecord.
7232     */
7233    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7234        // Update the task description to reflect any changes in the task stack
7235        tr.updateTaskDescription();
7236
7237        // Compose the recent task info
7238        ActivityManager.RecentTaskInfo rti
7239                = new ActivityManager.RecentTaskInfo();
7240        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7241        rti.persistentId = tr.taskId;
7242        rti.baseIntent = new Intent(tr.getBaseIntent());
7243        rti.origActivity = tr.origActivity;
7244        rti.description = tr.lastDescription;
7245        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7246        rti.userId = tr.userId;
7247        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7248        rti.lastActiveTime = tr.lastActiveTime;
7249        return rti;
7250    }
7251
7252    @Override
7253    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
7254            int flags, int userId) {
7255        final int callingUid = Binder.getCallingUid();
7256        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7257                false, true, "getRecentTasks", null);
7258
7259        synchronized (this) {
7260            final boolean allowed = checkCallingPermission(
7261                    android.Manifest.permission.GET_TASKS)
7262                    == PackageManager.PERMISSION_GRANTED;
7263            if (!allowed) {
7264                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7265                        + " does not hold GET_TASKS; limiting output");
7266            }
7267            final boolean detailed = checkCallingPermission(
7268                    android.Manifest.permission.GET_DETAILED_TASKS)
7269                    == PackageManager.PERMISSION_GRANTED;
7270
7271            IPackageManager pm = AppGlobals.getPackageManager();
7272
7273            final int N = mRecentTasks.size();
7274            ArrayList<ActivityManager.RecentTaskInfo> res
7275                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7276                            maxNum < N ? maxNum : N);
7277
7278            final Set<Integer> includedUsers;
7279            if ((flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0) {
7280                includedUsers = getProfileIdsLocked(userId);
7281            } else {
7282                includedUsers = new HashSet<Integer>();
7283            }
7284            includedUsers.add(Integer.valueOf(userId));
7285            for (int i=0; i<N && maxNum > 0; i++) {
7286                TaskRecord tr = mRecentTasks.get(i);
7287                // Only add calling user or related users recent tasks
7288                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7289
7290                // Return the entry if desired by the caller.  We always return
7291                // the first entry, because callers always expect this to be the
7292                // foreground app.  We may filter others if the caller has
7293                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7294                // we should exclude the entry.
7295
7296                if (i == 0
7297                        || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
7298                        || (tr.intent == null)
7299                        || ((tr.intent.getFlags()
7300                                &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
7301                    if (!allowed) {
7302                        // If the caller doesn't have the GET_TASKS permission, then only
7303                        // allow them to see a small subset of tasks -- their own and home.
7304                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7305                            continue;
7306                        }
7307                    }
7308                    if (tr.intent != null &&
7309                            (tr.intent.getFlags() & Intent.FLAG_ACTIVITY_AUTO_REMOVE_FROM_RECENTS)
7310                            != 0 && tr.getTopActivity() == null) {
7311                        // Don't include auto remove tasks that are finished or finishing.
7312                        continue;
7313                    }
7314
7315                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7316                    if (!detailed) {
7317                        rti.baseIntent.replaceExtras((Bundle)null);
7318                    }
7319
7320                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7321                        // Check whether this activity is currently available.
7322                        try {
7323                            if (rti.origActivity != null) {
7324                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7325                                        == null) {
7326                                    continue;
7327                                }
7328                            } else if (rti.baseIntent != null) {
7329                                if (pm.queryIntentActivities(rti.baseIntent,
7330                                        null, 0, userId) == null) {
7331                                    continue;
7332                                }
7333                            }
7334                        } catch (RemoteException e) {
7335                            // Will never happen.
7336                        }
7337                    }
7338
7339                    res.add(rti);
7340                    maxNum--;
7341                }
7342            }
7343            return res;
7344        }
7345    }
7346
7347    private TaskRecord recentTaskForIdLocked(int id) {
7348        final int N = mRecentTasks.size();
7349            for (int i=0; i<N; i++) {
7350                TaskRecord tr = mRecentTasks.get(i);
7351                if (tr.taskId == id) {
7352                    return tr;
7353                }
7354            }
7355            return null;
7356    }
7357
7358    @Override
7359    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7360        synchronized (this) {
7361            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7362                    "getTaskThumbnail()");
7363            TaskRecord tr = recentTaskForIdLocked(id);
7364            if (tr != null) {
7365                return tr.getTaskThumbnailLocked();
7366            }
7367        }
7368        return null;
7369    }
7370
7371    @Override
7372    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7373        synchronized (this) {
7374            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7375            if (r != null) {
7376                r.taskDescription = td;
7377                r.task.updateTaskDescription();
7378            }
7379        }
7380    }
7381
7382    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7383        if (!pr.killedByAm) {
7384            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7385            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7386                    pr.processName, pr.setAdj, reason);
7387            pr.killedByAm = true;
7388            Process.killProcessQuiet(pr.pid);
7389        }
7390    }
7391
7392    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7393        tr.disposeThumbnail();
7394        mRecentTasks.remove(tr);
7395        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7396        Intent baseIntent = new Intent(
7397                tr.intent != null ? tr.intent : tr.affinityIntent);
7398        ComponentName component = baseIntent.getComponent();
7399        if (component == null) {
7400            Slog.w(TAG, "Now component for base intent of task: " + tr);
7401            return;
7402        }
7403
7404        // Find any running services associated with this app.
7405        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7406
7407        if (killProcesses) {
7408            // Find any running processes associated with this app.
7409            final String pkg = component.getPackageName();
7410            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7411            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7412            for (int i=0; i<pmap.size(); i++) {
7413                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7414                for (int j=0; j<uids.size(); j++) {
7415                    ProcessRecord proc = uids.valueAt(j);
7416                    if (proc.userId != tr.userId) {
7417                        continue;
7418                    }
7419                    if (!proc.pkgList.containsKey(pkg)) {
7420                        continue;
7421                    }
7422                    procs.add(proc);
7423                }
7424            }
7425
7426            // Kill the running processes.
7427            for (int i=0; i<procs.size(); i++) {
7428                ProcessRecord pr = procs.get(i);
7429                if (pr == mHomeProcess) {
7430                    // Don't kill the home process along with tasks from the same package.
7431                    continue;
7432                }
7433                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7434                    killUnneededProcessLocked(pr, "remove task");
7435                } else {
7436                    pr.waitingToKill = "remove task";
7437                }
7438            }
7439        }
7440    }
7441
7442    /**
7443     * Removes the task with the specified task id.
7444     *
7445     * @param taskId Identifier of the task to be removed.
7446     * @param flags Additional operational flags.  May be 0 or
7447     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7448     * @return Returns true if the given task was found and removed.
7449     */
7450    private boolean removeTaskByIdLocked(int taskId, int flags) {
7451        TaskRecord tr = recentTaskForIdLocked(taskId);
7452        if (tr != null) {
7453            tr.removeTaskActivitiesLocked();
7454            cleanUpRemovedTaskLocked(tr, flags);
7455            if (tr.isPersistable) {
7456                notifyTaskPersisterLocked(tr, true);
7457            }
7458            return true;
7459        }
7460        return false;
7461    }
7462
7463    @Override
7464    public boolean removeTask(int taskId, int flags) {
7465        synchronized (this) {
7466            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7467                    "removeTask()");
7468            long ident = Binder.clearCallingIdentity();
7469            try {
7470                return removeTaskByIdLocked(taskId, flags);
7471            } finally {
7472                Binder.restoreCallingIdentity(ident);
7473            }
7474        }
7475    }
7476
7477    /**
7478     * TODO: Add mController hook
7479     */
7480    @Override
7481    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7482        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7483                "moveTaskToFront()");
7484
7485        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7486        synchronized(this) {
7487            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7488                    Binder.getCallingUid(), "Task to front")) {
7489                ActivityOptions.abort(options);
7490                return;
7491            }
7492            final long origId = Binder.clearCallingIdentity();
7493            try {
7494                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7495                if (task == null) {
7496                    return;
7497                }
7498                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7499                    mStackSupervisor.showLockTaskToast();
7500                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7501                    return;
7502                }
7503                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7504                if (prev != null && prev.isRecentsActivity()) {
7505                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7506                }
7507                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7508            } finally {
7509                Binder.restoreCallingIdentity(origId);
7510            }
7511            ActivityOptions.abort(options);
7512        }
7513    }
7514
7515    @Override
7516    public void moveTaskToBack(int taskId) {
7517        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7518                "moveTaskToBack()");
7519
7520        synchronized(this) {
7521            TaskRecord tr = recentTaskForIdLocked(taskId);
7522            if (tr != null) {
7523                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7524                ActivityStack stack = tr.stack;
7525                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7526                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7527                            Binder.getCallingUid(), "Task to back")) {
7528                        return;
7529                    }
7530                }
7531                final long origId = Binder.clearCallingIdentity();
7532                try {
7533                    stack.moveTaskToBackLocked(taskId, null);
7534                } finally {
7535                    Binder.restoreCallingIdentity(origId);
7536                }
7537            }
7538        }
7539    }
7540
7541    /**
7542     * Moves an activity, and all of the other activities within the same task, to the bottom
7543     * of the history stack.  The activity's order within the task is unchanged.
7544     *
7545     * @param token A reference to the activity we wish to move
7546     * @param nonRoot If false then this only works if the activity is the root
7547     *                of a task; if true it will work for any activity in a task.
7548     * @return Returns true if the move completed, false if not.
7549     */
7550    @Override
7551    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7552        enforceNotIsolatedCaller("moveActivityTaskToBack");
7553        synchronized(this) {
7554            final long origId = Binder.clearCallingIdentity();
7555            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7556            if (taskId >= 0) {
7557                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7558            }
7559            Binder.restoreCallingIdentity(origId);
7560        }
7561        return false;
7562    }
7563
7564    @Override
7565    public void moveTaskBackwards(int task) {
7566        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7567                "moveTaskBackwards()");
7568
7569        synchronized(this) {
7570            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7571                    Binder.getCallingUid(), "Task backwards")) {
7572                return;
7573            }
7574            final long origId = Binder.clearCallingIdentity();
7575            moveTaskBackwardsLocked(task);
7576            Binder.restoreCallingIdentity(origId);
7577        }
7578    }
7579
7580    private final void moveTaskBackwardsLocked(int task) {
7581        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7582    }
7583
7584    @Override
7585    public IBinder getHomeActivityToken() throws RemoteException {
7586        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7587                "getHomeActivityToken()");
7588        synchronized (this) {
7589            return mStackSupervisor.getHomeActivityToken();
7590        }
7591    }
7592
7593    @Override
7594    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7595            IActivityContainerCallback callback) throws RemoteException {
7596        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7597                "createActivityContainer()");
7598        synchronized (this) {
7599            if (parentActivityToken == null) {
7600                throw new IllegalArgumentException("parent token must not be null");
7601            }
7602            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7603            if (r == null) {
7604                return null;
7605            }
7606            if (callback == null) {
7607                throw new IllegalArgumentException("callback must not be null");
7608            }
7609            return mStackSupervisor.createActivityContainer(r, callback);
7610        }
7611    }
7612
7613    @Override
7614    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7615        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7616                "deleteActivityContainer()");
7617        synchronized (this) {
7618            mStackSupervisor.deleteActivityContainer(container);
7619        }
7620    }
7621
7622    @Override
7623    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7624            throws RemoteException {
7625        synchronized (this) {
7626            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7627            if (stack != null) {
7628                return stack.mActivityContainer;
7629            }
7630            return null;
7631        }
7632    }
7633
7634    @Override
7635    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7636        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7637                "moveTaskToStack()");
7638        if (stackId == HOME_STACK_ID) {
7639            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7640                    new RuntimeException("here").fillInStackTrace());
7641        }
7642        synchronized (this) {
7643            long ident = Binder.clearCallingIdentity();
7644            try {
7645                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7646                        + stackId + " toTop=" + toTop);
7647                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7648            } finally {
7649                Binder.restoreCallingIdentity(ident);
7650            }
7651        }
7652    }
7653
7654    @Override
7655    public void resizeStack(int stackBoxId, Rect bounds) {
7656        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7657                "resizeStackBox()");
7658        long ident = Binder.clearCallingIdentity();
7659        try {
7660            mWindowManager.resizeStack(stackBoxId, bounds);
7661        } finally {
7662            Binder.restoreCallingIdentity(ident);
7663        }
7664    }
7665
7666    @Override
7667    public List<StackInfo> getAllStackInfos() {
7668        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7669                "getAllStackInfos()");
7670        long ident = Binder.clearCallingIdentity();
7671        try {
7672            synchronized (this) {
7673                return mStackSupervisor.getAllStackInfosLocked();
7674            }
7675        } finally {
7676            Binder.restoreCallingIdentity(ident);
7677        }
7678    }
7679
7680    @Override
7681    public StackInfo getStackInfo(int stackId) {
7682        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7683                "getStackInfo()");
7684        long ident = Binder.clearCallingIdentity();
7685        try {
7686            synchronized (this) {
7687                return mStackSupervisor.getStackInfoLocked(stackId);
7688            }
7689        } finally {
7690            Binder.restoreCallingIdentity(ident);
7691        }
7692    }
7693
7694    @Override
7695    public boolean isInHomeStack(int taskId) {
7696        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7697                "getStackInfo()");
7698        long ident = Binder.clearCallingIdentity();
7699        try {
7700            synchronized (this) {
7701                TaskRecord tr = recentTaskForIdLocked(taskId);
7702                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7703            }
7704        } finally {
7705            Binder.restoreCallingIdentity(ident);
7706        }
7707    }
7708
7709    @Override
7710    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7711        synchronized(this) {
7712            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7713        }
7714    }
7715
7716    private boolean isLockTaskAuthorized(String pkg) {
7717        final DevicePolicyManager dpm = (DevicePolicyManager)
7718                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7719        try {
7720            int uid = mContext.getPackageManager().getPackageUid(pkg,
7721                    Binder.getCallingUserHandle().getIdentifier());
7722            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7723        } catch (NameNotFoundException e) {
7724            return false;
7725        }
7726    }
7727
7728    void startLockTaskMode(TaskRecord task) {
7729        final String pkg;
7730        synchronized (this) {
7731            pkg = task.intent.getComponent().getPackageName();
7732        }
7733        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7734        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7735            final TaskRecord taskRecord = task;
7736            mHandler.post(new Runnable() {
7737                @Override
7738                public void run() {
7739                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7740                }
7741            });
7742            return;
7743        }
7744        long ident = Binder.clearCallingIdentity();
7745        try {
7746            synchronized (this) {
7747                // Since we lost lock on task, make sure it is still there.
7748                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7749                if (task != null) {
7750                    if (!isSystemInitiated
7751                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7752                        throw new IllegalArgumentException("Invalid task, not in foreground");
7753                    }
7754                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7755                }
7756            }
7757        } finally {
7758            Binder.restoreCallingIdentity(ident);
7759        }
7760    }
7761
7762    @Override
7763    public void startLockTaskMode(int taskId) {
7764        final TaskRecord task;
7765        long ident = Binder.clearCallingIdentity();
7766        try {
7767            synchronized (this) {
7768                task = mStackSupervisor.anyTaskForIdLocked(taskId);
7769            }
7770        } finally {
7771            Binder.restoreCallingIdentity(ident);
7772        }
7773        if (task != null) {
7774            startLockTaskMode(task);
7775        }
7776    }
7777
7778    @Override
7779    public void startLockTaskMode(IBinder token) {
7780        final TaskRecord task;
7781        long ident = Binder.clearCallingIdentity();
7782        try {
7783            synchronized (this) {
7784                final ActivityRecord r = ActivityRecord.forToken(token);
7785                if (r == null) {
7786                    return;
7787                }
7788                task = r.task;
7789            }
7790        } finally {
7791            Binder.restoreCallingIdentity(ident);
7792        }
7793        if (task != null) {
7794            startLockTaskMode(task);
7795        }
7796    }
7797
7798    @Override
7799    public void startLockTaskModeOnCurrent() throws RemoteException {
7800        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7801        ActivityRecord r = null;
7802        synchronized (this) {
7803            r = mStackSupervisor.topRunningActivityLocked();
7804        }
7805        startLockTaskMode(r.task);
7806    }
7807
7808    @Override
7809    public void stopLockTaskMode() {
7810        // Verify that the user matches the package of the intent for the TaskRecord
7811        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
7812        // and stopLockTaskMode.
7813        final int callingUid = Binder.getCallingUid();
7814        if (callingUid != Process.SYSTEM_UID) {
7815            try {
7816                String pkg =
7817                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
7818                int uid = mContext.getPackageManager().getPackageUid(pkg,
7819                        Binder.getCallingUserHandle().getIdentifier());
7820                if (uid != callingUid) {
7821                    throw new SecurityException("Invalid uid, expected " + uid);
7822                }
7823            } catch (NameNotFoundException e) {
7824                Log.d(TAG, "stopLockTaskMode " + e);
7825                return;
7826            }
7827        }
7828        long ident = Binder.clearCallingIdentity();
7829        try {
7830            Log.d(TAG, "stopLockTaskMode");
7831            // Stop lock task
7832            synchronized (this) {
7833                mStackSupervisor.setLockTaskModeLocked(null, false);
7834            }
7835        } finally {
7836            Binder.restoreCallingIdentity(ident);
7837        }
7838    }
7839
7840    @Override
7841    public void stopLockTaskModeOnCurrent() throws RemoteException {
7842        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
7843        long ident = Binder.clearCallingIdentity();
7844        try {
7845            stopLockTaskMode();
7846        } finally {
7847            Binder.restoreCallingIdentity(ident);
7848        }
7849    }
7850
7851    @Override
7852    public boolean isInLockTaskMode() {
7853        synchronized (this) {
7854            return mStackSupervisor.isInLockTaskMode();
7855        }
7856    }
7857
7858    // =========================================================
7859    // CONTENT PROVIDERS
7860    // =========================================================
7861
7862    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
7863        List<ProviderInfo> providers = null;
7864        try {
7865            providers = AppGlobals.getPackageManager().
7866                queryContentProviders(app.processName, app.uid,
7867                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
7868        } catch (RemoteException ex) {
7869        }
7870        if (DEBUG_MU)
7871            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
7872        int userId = app.userId;
7873        if (providers != null) {
7874            int N = providers.size();
7875            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
7876            for (int i=0; i<N; i++) {
7877                ProviderInfo cpi =
7878                    (ProviderInfo)providers.get(i);
7879                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
7880                        cpi.name, cpi.flags);
7881                if (singleton && UserHandle.getUserId(app.uid) != 0) {
7882                    // This is a singleton provider, but a user besides the
7883                    // default user is asking to initialize a process it runs
7884                    // in...  well, no, it doesn't actually run in this process,
7885                    // it runs in the process of the default user.  Get rid of it.
7886                    providers.remove(i);
7887                    N--;
7888                    i--;
7889                    continue;
7890                }
7891
7892                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
7893                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
7894                if (cpr == null) {
7895                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
7896                    mProviderMap.putProviderByClass(comp, cpr);
7897                }
7898                if (DEBUG_MU)
7899                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
7900                app.pubProviders.put(cpi.name, cpr);
7901                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
7902                    // Don't add this if it is a platform component that is marked
7903                    // to run in multiple processes, because this is actually
7904                    // part of the framework so doesn't make sense to track as a
7905                    // separate apk in the process.
7906                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
7907                            mProcessStats);
7908                }
7909                ensurePackageDexOpt(cpi.applicationInfo.packageName);
7910            }
7911        }
7912        return providers;
7913    }
7914
7915    /**
7916     * Check if {@link ProcessRecord} has a possible chance at accessing the
7917     * given {@link ProviderInfo}. Final permission checking is always done
7918     * in {@link ContentProvider}.
7919     */
7920    private final String checkContentProviderPermissionLocked(
7921            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
7922        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
7923        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
7924        boolean checkedGrants = false;
7925        if (checkUser) {
7926            // Looking for cross-user grants before enforcing the typical cross-users permissions
7927            if (UserHandle.getUserId(callingUid) != userId) {
7928                if (checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7929                    return null;
7930                }
7931                checkedGrants = true;
7932            }
7933            userId = handleIncomingUser(callingPid, callingUid, userId,
7934                    false, true, "checkContentProviderPermissionLocked " + cpi.authority, null);
7935        }
7936        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
7937                cpi.applicationInfo.uid, cpi.exported)
7938                == PackageManager.PERMISSION_GRANTED) {
7939            return null;
7940        }
7941        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
7942                cpi.applicationInfo.uid, cpi.exported)
7943                == PackageManager.PERMISSION_GRANTED) {
7944            return null;
7945        }
7946
7947        PathPermission[] pps = cpi.pathPermissions;
7948        if (pps != null) {
7949            int i = pps.length;
7950            while (i > 0) {
7951                i--;
7952                PathPermission pp = pps[i];
7953                String pprperm = pp.getReadPermission();
7954                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
7955                        cpi.applicationInfo.uid, cpi.exported)
7956                        == PackageManager.PERMISSION_GRANTED) {
7957                    return null;
7958                }
7959                String ppwperm = pp.getWritePermission();
7960                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
7961                        cpi.applicationInfo.uid, cpi.exported)
7962                        == PackageManager.PERMISSION_GRANTED) {
7963                    return null;
7964                }
7965            }
7966        }
7967        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
7968            return null;
7969        }
7970
7971        String msg;
7972        if (!cpi.exported) {
7973            msg = "Permission Denial: opening provider " + cpi.name
7974                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7975                    + ", uid=" + callingUid + ") that is not exported from uid "
7976                    + cpi.applicationInfo.uid;
7977        } else {
7978            msg = "Permission Denial: opening provider " + cpi.name
7979                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
7980                    + ", uid=" + callingUid + ") requires "
7981                    + cpi.readPermission + " or " + cpi.writePermission;
7982        }
7983        Slog.w(TAG, msg);
7984        return msg;
7985    }
7986
7987    /**
7988     * Returns if the ContentProvider has granted a uri to callingUid
7989     */
7990    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
7991        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
7992        if (perms != null) {
7993            for (GrantUri grantUri : perms.keySet()) {
7994                if (grantUri.sourceUserId == userId || !checkUser) {
7995                    if (matchesProvider(grantUri.uri, cpi)) {
7996                        return true;
7997                    }
7998                }
7999            }
8000        }
8001        return false;
8002    }
8003
8004    /**
8005     * Returns true if the uri authority is one of the authorities specified in the provider.
8006     */
8007    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8008        String uriAuth = uri.getAuthority();
8009        String cpiAuth = cpi.authority;
8010        if (cpiAuth.indexOf(';') == -1) {
8011            return cpiAuth.equals(uriAuth);
8012        }
8013        String[] cpiAuths = cpiAuth.split(";");
8014        int length = cpiAuths.length;
8015        for (int i = 0; i < length; i++) {
8016            if (cpiAuths[i].equals(uriAuth)) return true;
8017        }
8018        return false;
8019    }
8020
8021    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8022            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8023        if (r != null) {
8024            for (int i=0; i<r.conProviders.size(); i++) {
8025                ContentProviderConnection conn = r.conProviders.get(i);
8026                if (conn.provider == cpr) {
8027                    if (DEBUG_PROVIDER) Slog.v(TAG,
8028                            "Adding provider requested by "
8029                            + r.processName + " from process "
8030                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8031                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8032                    if (stable) {
8033                        conn.stableCount++;
8034                        conn.numStableIncs++;
8035                    } else {
8036                        conn.unstableCount++;
8037                        conn.numUnstableIncs++;
8038                    }
8039                    return conn;
8040                }
8041            }
8042            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8043            if (stable) {
8044                conn.stableCount = 1;
8045                conn.numStableIncs = 1;
8046            } else {
8047                conn.unstableCount = 1;
8048                conn.numUnstableIncs = 1;
8049            }
8050            cpr.connections.add(conn);
8051            r.conProviders.add(conn);
8052            return conn;
8053        }
8054        cpr.addExternalProcessHandleLocked(externalProcessToken);
8055        return null;
8056    }
8057
8058    boolean decProviderCountLocked(ContentProviderConnection conn,
8059            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8060        if (conn != null) {
8061            cpr = conn.provider;
8062            if (DEBUG_PROVIDER) Slog.v(TAG,
8063                    "Removing provider requested by "
8064                    + conn.client.processName + " from process "
8065                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8066                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8067            if (stable) {
8068                conn.stableCount--;
8069            } else {
8070                conn.unstableCount--;
8071            }
8072            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8073                cpr.connections.remove(conn);
8074                conn.client.conProviders.remove(conn);
8075                return true;
8076            }
8077            return false;
8078        }
8079        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8080        return false;
8081    }
8082
8083    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8084            String name, IBinder token, boolean stable, int userId) {
8085        ContentProviderRecord cpr;
8086        ContentProviderConnection conn = null;
8087        ProviderInfo cpi = null;
8088
8089        synchronized(this) {
8090            ProcessRecord r = null;
8091            if (caller != null) {
8092                r = getRecordForAppLocked(caller);
8093                if (r == null) {
8094                    throw new SecurityException(
8095                            "Unable to find app for caller " + caller
8096                          + " (pid=" + Binder.getCallingPid()
8097                          + ") when getting content provider " + name);
8098                }
8099            }
8100
8101            boolean checkCrossUser = true;
8102
8103            // First check if this content provider has been published...
8104            cpr = mProviderMap.getProviderByName(name, userId);
8105            // If that didn't work, check if it exists for user 0 and then
8106            // verify that it's a singleton provider before using it.
8107            if (cpr == null && userId != UserHandle.USER_OWNER) {
8108                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8109                if (cpr != null) {
8110                    cpi = cpr.info;
8111                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8112                            cpi.name, cpi.flags)
8113                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8114                        userId = UserHandle.USER_OWNER;
8115                        checkCrossUser = false;
8116                    } else {
8117                        cpr = null;
8118                        cpi = null;
8119                    }
8120                }
8121            }
8122
8123            boolean providerRunning = cpr != null;
8124            if (providerRunning) {
8125                cpi = cpr.info;
8126                String msg;
8127                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8128                        != null) {
8129                    throw new SecurityException(msg);
8130                }
8131
8132                if (r != null && cpr.canRunHere(r)) {
8133                    // This provider has been published or is in the process
8134                    // of being published...  but it is also allowed to run
8135                    // in the caller's process, so don't make a connection
8136                    // and just let the caller instantiate its own instance.
8137                    ContentProviderHolder holder = cpr.newHolder(null);
8138                    // don't give caller the provider object, it needs
8139                    // to make its own.
8140                    holder.provider = null;
8141                    return holder;
8142                }
8143
8144                final long origId = Binder.clearCallingIdentity();
8145
8146                // In this case the provider instance already exists, so we can
8147                // return it right away.
8148                conn = incProviderCountLocked(r, cpr, token, stable);
8149                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8150                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8151                        // If this is a perceptible app accessing the provider,
8152                        // make sure to count it as being accessed and thus
8153                        // back up on the LRU list.  This is good because
8154                        // content providers are often expensive to start.
8155                        updateLruProcessLocked(cpr.proc, false, null);
8156                    }
8157                }
8158
8159                if (cpr.proc != null) {
8160                    if (false) {
8161                        if (cpr.name.flattenToShortString().equals(
8162                                "com.android.providers.calendar/.CalendarProvider2")) {
8163                            Slog.v(TAG, "****************** KILLING "
8164                                + cpr.name.flattenToShortString());
8165                            Process.killProcess(cpr.proc.pid);
8166                        }
8167                    }
8168                    boolean success = updateOomAdjLocked(cpr.proc);
8169                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8170                    // NOTE: there is still a race here where a signal could be
8171                    // pending on the process even though we managed to update its
8172                    // adj level.  Not sure what to do about this, but at least
8173                    // the race is now smaller.
8174                    if (!success) {
8175                        // Uh oh...  it looks like the provider's process
8176                        // has been killed on us.  We need to wait for a new
8177                        // process to be started, and make sure its death
8178                        // doesn't kill our process.
8179                        Slog.i(TAG,
8180                                "Existing provider " + cpr.name.flattenToShortString()
8181                                + " is crashing; detaching " + r);
8182                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8183                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8184                        if (!lastRef) {
8185                            // This wasn't the last ref our process had on
8186                            // the provider...  we have now been killed, bail.
8187                            return null;
8188                        }
8189                        providerRunning = false;
8190                        conn = null;
8191                    }
8192                }
8193
8194                Binder.restoreCallingIdentity(origId);
8195            }
8196
8197            boolean singleton;
8198            if (!providerRunning) {
8199                try {
8200                    cpi = AppGlobals.getPackageManager().
8201                        resolveContentProvider(name,
8202                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8203                } catch (RemoteException ex) {
8204                }
8205                if (cpi == null) {
8206                    return null;
8207                }
8208                // If the provider is a singleton AND
8209                // (it's a call within the same user || the provider is a
8210                // privileged app)
8211                // Then allow connecting to the singleton provider
8212                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8213                        cpi.name, cpi.flags)
8214                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8215                if (singleton) {
8216                    userId = UserHandle.USER_OWNER;
8217                }
8218                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8219
8220                String msg;
8221                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8222                        != null) {
8223                    throw new SecurityException(msg);
8224                }
8225
8226                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8227                        && !cpi.processName.equals("system")) {
8228                    // If this content provider does not run in the system
8229                    // process, and the system is not yet ready to run other
8230                    // processes, then fail fast instead of hanging.
8231                    throw new IllegalArgumentException(
8232                            "Attempt to launch content provider before system ready");
8233                }
8234
8235                // Make sure that the user who owns this provider is started.  If not,
8236                // we don't want to allow it to run.
8237                if (mStartedUsers.get(userId) == null) {
8238                    Slog.w(TAG, "Unable to launch app "
8239                            + cpi.applicationInfo.packageName + "/"
8240                            + cpi.applicationInfo.uid + " for provider "
8241                            + name + ": user " + userId + " is stopped");
8242                    return null;
8243                }
8244
8245                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8246                cpr = mProviderMap.getProviderByClass(comp, userId);
8247                final boolean firstClass = cpr == null;
8248                if (firstClass) {
8249                    try {
8250                        ApplicationInfo ai =
8251                            AppGlobals.getPackageManager().
8252                                getApplicationInfo(
8253                                        cpi.applicationInfo.packageName,
8254                                        STOCK_PM_FLAGS, userId);
8255                        if (ai == null) {
8256                            Slog.w(TAG, "No package info for content provider "
8257                                    + cpi.name);
8258                            return null;
8259                        }
8260                        ai = getAppInfoForUser(ai, userId);
8261                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8262                    } catch (RemoteException ex) {
8263                        // pm is in same process, this will never happen.
8264                    }
8265                }
8266
8267                if (r != null && cpr.canRunHere(r)) {
8268                    // If this is a multiprocess provider, then just return its
8269                    // info and allow the caller to instantiate it.  Only do
8270                    // this if the provider is the same user as the caller's
8271                    // process, or can run as root (so can be in any process).
8272                    return cpr.newHolder(null);
8273                }
8274
8275                if (DEBUG_PROVIDER) {
8276                    RuntimeException e = new RuntimeException("here");
8277                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8278                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8279                }
8280
8281                // This is single process, and our app is now connecting to it.
8282                // See if we are already in the process of launching this
8283                // provider.
8284                final int N = mLaunchingProviders.size();
8285                int i;
8286                for (i=0; i<N; i++) {
8287                    if (mLaunchingProviders.get(i) == cpr) {
8288                        break;
8289                    }
8290                }
8291
8292                // If the provider is not already being launched, then get it
8293                // started.
8294                if (i >= N) {
8295                    final long origId = Binder.clearCallingIdentity();
8296
8297                    try {
8298                        // Content provider is now in use, its package can't be stopped.
8299                        try {
8300                            AppGlobals.getPackageManager().setPackageStoppedState(
8301                                    cpr.appInfo.packageName, false, userId);
8302                        } catch (RemoteException e) {
8303                        } catch (IllegalArgumentException e) {
8304                            Slog.w(TAG, "Failed trying to unstop package "
8305                                    + cpr.appInfo.packageName + ": " + e);
8306                        }
8307
8308                        // Use existing process if already started
8309                        ProcessRecord proc = getProcessRecordLocked(
8310                                cpi.processName, cpr.appInfo.uid, false);
8311                        if (proc != null && proc.thread != null) {
8312                            if (DEBUG_PROVIDER) {
8313                                Slog.d(TAG, "Installing in existing process " + proc);
8314                            }
8315                            proc.pubProviders.put(cpi.name, cpr);
8316                            try {
8317                                proc.thread.scheduleInstallProvider(cpi);
8318                            } catch (RemoteException e) {
8319                            }
8320                        } else {
8321                            proc = startProcessLocked(cpi.processName,
8322                                    cpr.appInfo, false, 0, "content provider",
8323                                    new ComponentName(cpi.applicationInfo.packageName,
8324                                            cpi.name), false, false, false);
8325                            if (proc == null) {
8326                                Slog.w(TAG, "Unable to launch app "
8327                                        + cpi.applicationInfo.packageName + "/"
8328                                        + cpi.applicationInfo.uid + " for provider "
8329                                        + name + ": process is bad");
8330                                return null;
8331                            }
8332                        }
8333                        cpr.launchingApp = proc;
8334                        mLaunchingProviders.add(cpr);
8335                    } finally {
8336                        Binder.restoreCallingIdentity(origId);
8337                    }
8338                }
8339
8340                // Make sure the provider is published (the same provider class
8341                // may be published under multiple names).
8342                if (firstClass) {
8343                    mProviderMap.putProviderByClass(comp, cpr);
8344                }
8345
8346                mProviderMap.putProviderByName(name, cpr);
8347                conn = incProviderCountLocked(r, cpr, token, stable);
8348                if (conn != null) {
8349                    conn.waiting = true;
8350                }
8351            }
8352        }
8353
8354        // Wait for the provider to be published...
8355        synchronized (cpr) {
8356            while (cpr.provider == null) {
8357                if (cpr.launchingApp == null) {
8358                    Slog.w(TAG, "Unable to launch app "
8359                            + cpi.applicationInfo.packageName + "/"
8360                            + cpi.applicationInfo.uid + " for provider "
8361                            + name + ": launching app became null");
8362                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8363                            UserHandle.getUserId(cpi.applicationInfo.uid),
8364                            cpi.applicationInfo.packageName,
8365                            cpi.applicationInfo.uid, name);
8366                    return null;
8367                }
8368                try {
8369                    if (DEBUG_MU) {
8370                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8371                                + cpr.launchingApp);
8372                    }
8373                    if (conn != null) {
8374                        conn.waiting = true;
8375                    }
8376                    cpr.wait();
8377                } catch (InterruptedException ex) {
8378                } finally {
8379                    if (conn != null) {
8380                        conn.waiting = false;
8381                    }
8382                }
8383            }
8384        }
8385        return cpr != null ? cpr.newHolder(conn) : null;
8386    }
8387
8388    @Override
8389    public final ContentProviderHolder getContentProvider(
8390            IApplicationThread caller, String name, int userId, boolean stable) {
8391        enforceNotIsolatedCaller("getContentProvider");
8392        if (caller == null) {
8393            String msg = "null IApplicationThread when getting content provider "
8394                    + name;
8395            Slog.w(TAG, msg);
8396            throw new SecurityException(msg);
8397        }
8398        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8399        // with cross-user grant.
8400        return getContentProviderImpl(caller, name, null, stable, userId);
8401    }
8402
8403    public ContentProviderHolder getContentProviderExternal(
8404            String name, int userId, IBinder token) {
8405        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8406            "Do not have permission in call getContentProviderExternal()");
8407        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8408                false, true, "getContentProvider", null);
8409        return getContentProviderExternalUnchecked(name, token, userId);
8410    }
8411
8412    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8413            IBinder token, int userId) {
8414        return getContentProviderImpl(null, name, token, true, userId);
8415    }
8416
8417    /**
8418     * Drop a content provider from a ProcessRecord's bookkeeping
8419     */
8420    public void removeContentProvider(IBinder connection, boolean stable) {
8421        enforceNotIsolatedCaller("removeContentProvider");
8422        long ident = Binder.clearCallingIdentity();
8423        try {
8424            synchronized (this) {
8425                ContentProviderConnection conn;
8426                try {
8427                    conn = (ContentProviderConnection)connection;
8428                } catch (ClassCastException e) {
8429                    String msg ="removeContentProvider: " + connection
8430                            + " not a ContentProviderConnection";
8431                    Slog.w(TAG, msg);
8432                    throw new IllegalArgumentException(msg);
8433                }
8434                if (conn == null) {
8435                    throw new NullPointerException("connection is null");
8436                }
8437                if (decProviderCountLocked(conn, null, null, stable)) {
8438                    updateOomAdjLocked();
8439                }
8440            }
8441        } finally {
8442            Binder.restoreCallingIdentity(ident);
8443        }
8444    }
8445
8446    public void removeContentProviderExternal(String name, IBinder token) {
8447        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8448            "Do not have permission in call removeContentProviderExternal()");
8449        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8450    }
8451
8452    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8453        synchronized (this) {
8454            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8455            if(cpr == null) {
8456                //remove from mProvidersByClass
8457                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8458                return;
8459            }
8460
8461            //update content provider record entry info
8462            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8463            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8464            if (localCpr.hasExternalProcessHandles()) {
8465                if (localCpr.removeExternalProcessHandleLocked(token)) {
8466                    updateOomAdjLocked();
8467                } else {
8468                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8469                            + " with no external reference for token: "
8470                            + token + ".");
8471                }
8472            } else {
8473                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8474                        + " with no external references.");
8475            }
8476        }
8477    }
8478
8479    public final void publishContentProviders(IApplicationThread caller,
8480            List<ContentProviderHolder> providers) {
8481        if (providers == null) {
8482            return;
8483        }
8484
8485        enforceNotIsolatedCaller("publishContentProviders");
8486        synchronized (this) {
8487            final ProcessRecord r = getRecordForAppLocked(caller);
8488            if (DEBUG_MU)
8489                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8490            if (r == null) {
8491                throw new SecurityException(
8492                        "Unable to find app for caller " + caller
8493                      + " (pid=" + Binder.getCallingPid()
8494                      + ") when publishing content providers");
8495            }
8496
8497            final long origId = Binder.clearCallingIdentity();
8498
8499            final int N = providers.size();
8500            for (int i=0; i<N; i++) {
8501                ContentProviderHolder src = providers.get(i);
8502                if (src == null || src.info == null || src.provider == null) {
8503                    continue;
8504                }
8505                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8506                if (DEBUG_MU)
8507                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8508                if (dst != null) {
8509                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8510                    mProviderMap.putProviderByClass(comp, dst);
8511                    String names[] = dst.info.authority.split(";");
8512                    for (int j = 0; j < names.length; j++) {
8513                        mProviderMap.putProviderByName(names[j], dst);
8514                    }
8515
8516                    int NL = mLaunchingProviders.size();
8517                    int j;
8518                    for (j=0; j<NL; j++) {
8519                        if (mLaunchingProviders.get(j) == dst) {
8520                            mLaunchingProviders.remove(j);
8521                            j--;
8522                            NL--;
8523                        }
8524                    }
8525                    synchronized (dst) {
8526                        dst.provider = src.provider;
8527                        dst.proc = r;
8528                        dst.notifyAll();
8529                    }
8530                    updateOomAdjLocked(r);
8531                }
8532            }
8533
8534            Binder.restoreCallingIdentity(origId);
8535        }
8536    }
8537
8538    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8539        ContentProviderConnection conn;
8540        try {
8541            conn = (ContentProviderConnection)connection;
8542        } catch (ClassCastException e) {
8543            String msg ="refContentProvider: " + connection
8544                    + " not a ContentProviderConnection";
8545            Slog.w(TAG, msg);
8546            throw new IllegalArgumentException(msg);
8547        }
8548        if (conn == null) {
8549            throw new NullPointerException("connection is null");
8550        }
8551
8552        synchronized (this) {
8553            if (stable > 0) {
8554                conn.numStableIncs += stable;
8555            }
8556            stable = conn.stableCount + stable;
8557            if (stable < 0) {
8558                throw new IllegalStateException("stableCount < 0: " + stable);
8559            }
8560
8561            if (unstable > 0) {
8562                conn.numUnstableIncs += unstable;
8563            }
8564            unstable = conn.unstableCount + unstable;
8565            if (unstable < 0) {
8566                throw new IllegalStateException("unstableCount < 0: " + unstable);
8567            }
8568
8569            if ((stable+unstable) <= 0) {
8570                throw new IllegalStateException("ref counts can't go to zero here: stable="
8571                        + stable + " unstable=" + unstable);
8572            }
8573            conn.stableCount = stable;
8574            conn.unstableCount = unstable;
8575            return !conn.dead;
8576        }
8577    }
8578
8579    public void unstableProviderDied(IBinder connection) {
8580        ContentProviderConnection conn;
8581        try {
8582            conn = (ContentProviderConnection)connection;
8583        } catch (ClassCastException e) {
8584            String msg ="refContentProvider: " + connection
8585                    + " not a ContentProviderConnection";
8586            Slog.w(TAG, msg);
8587            throw new IllegalArgumentException(msg);
8588        }
8589        if (conn == null) {
8590            throw new NullPointerException("connection is null");
8591        }
8592
8593        // Safely retrieve the content provider associated with the connection.
8594        IContentProvider provider;
8595        synchronized (this) {
8596            provider = conn.provider.provider;
8597        }
8598
8599        if (provider == null) {
8600            // Um, yeah, we're way ahead of you.
8601            return;
8602        }
8603
8604        // Make sure the caller is being honest with us.
8605        if (provider.asBinder().pingBinder()) {
8606            // Er, no, still looks good to us.
8607            synchronized (this) {
8608                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8609                        + " says " + conn + " died, but we don't agree");
8610                return;
8611            }
8612        }
8613
8614        // Well look at that!  It's dead!
8615        synchronized (this) {
8616            if (conn.provider.provider != provider) {
8617                // But something changed...  good enough.
8618                return;
8619            }
8620
8621            ProcessRecord proc = conn.provider.proc;
8622            if (proc == null || proc.thread == null) {
8623                // Seems like the process is already cleaned up.
8624                return;
8625            }
8626
8627            // As far as we're concerned, this is just like receiving a
8628            // death notification...  just a bit prematurely.
8629            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8630                    + ") early provider death");
8631            final long ident = Binder.clearCallingIdentity();
8632            try {
8633                appDiedLocked(proc, proc.pid, proc.thread);
8634            } finally {
8635                Binder.restoreCallingIdentity(ident);
8636            }
8637        }
8638    }
8639
8640    @Override
8641    public void appNotRespondingViaProvider(IBinder connection) {
8642        enforceCallingPermission(
8643                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8644
8645        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8646        if (conn == null) {
8647            Slog.w(TAG, "ContentProviderConnection is null");
8648            return;
8649        }
8650
8651        final ProcessRecord host = conn.provider.proc;
8652        if (host == null) {
8653            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8654            return;
8655        }
8656
8657        final long token = Binder.clearCallingIdentity();
8658        try {
8659            appNotResponding(host, null, null, false, "ContentProvider not responding");
8660        } finally {
8661            Binder.restoreCallingIdentity(token);
8662        }
8663    }
8664
8665    public final void installSystemProviders() {
8666        List<ProviderInfo> providers;
8667        synchronized (this) {
8668            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8669            providers = generateApplicationProvidersLocked(app);
8670            if (providers != null) {
8671                for (int i=providers.size()-1; i>=0; i--) {
8672                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8673                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8674                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8675                                + ": not system .apk");
8676                        providers.remove(i);
8677                    }
8678                }
8679            }
8680        }
8681        if (providers != null) {
8682            mSystemThread.installSystemProviders(providers);
8683        }
8684
8685        mCoreSettingsObserver = new CoreSettingsObserver(this);
8686
8687        mUsageStatsService.monitorPackages();
8688    }
8689
8690    /**
8691     * Allows app to retrieve the MIME type of a URI without having permission
8692     * to access its content provider.
8693     *
8694     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8695     *
8696     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8697     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8698     */
8699    public String getProviderMimeType(Uri uri, int userId) {
8700        enforceNotIsolatedCaller("getProviderMimeType");
8701        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8702                userId, false, true, "getProviderMimeType", null);
8703        final String name = uri.getAuthority();
8704        final long ident = Binder.clearCallingIdentity();
8705        ContentProviderHolder holder = null;
8706
8707        try {
8708            holder = getContentProviderExternalUnchecked(name, null, userId);
8709            if (holder != null) {
8710                return holder.provider.getType(uri);
8711            }
8712        } catch (RemoteException e) {
8713            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8714            return null;
8715        } finally {
8716            if (holder != null) {
8717                removeContentProviderExternalUnchecked(name, null, userId);
8718            }
8719            Binder.restoreCallingIdentity(ident);
8720        }
8721
8722        return null;
8723    }
8724
8725    // =========================================================
8726    // GLOBAL MANAGEMENT
8727    // =========================================================
8728
8729    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8730            boolean isolated) {
8731        String proc = customProcess != null ? customProcess : info.processName;
8732        BatteryStatsImpl.Uid.Proc ps = null;
8733        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8734        int uid = info.uid;
8735        if (isolated) {
8736            int userId = UserHandle.getUserId(uid);
8737            int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8738            while (true) {
8739                if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8740                        || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8741                    mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8742                }
8743                uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8744                mNextIsolatedProcessUid++;
8745                if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8746                    // No process for this uid, use it.
8747                    break;
8748                }
8749                stepsLeft--;
8750                if (stepsLeft <= 0) {
8751                    return null;
8752                }
8753            }
8754        }
8755        return new ProcessRecord(stats, info, proc, uid);
8756    }
8757
8758    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
8759            String abiOverride) {
8760        ProcessRecord app;
8761        if (!isolated) {
8762            app = getProcessRecordLocked(info.processName, info.uid, true);
8763        } else {
8764            app = null;
8765        }
8766
8767        if (app == null) {
8768            app = newProcessRecordLocked(info, null, isolated);
8769            mProcessNames.put(info.processName, app.uid, app);
8770            if (isolated) {
8771                mIsolatedProcesses.put(app.uid, app);
8772            }
8773            updateLruProcessLocked(app, false, null);
8774            updateOomAdjLocked();
8775        }
8776
8777        // This package really, really can not be stopped.
8778        try {
8779            AppGlobals.getPackageManager().setPackageStoppedState(
8780                    info.packageName, false, UserHandle.getUserId(app.uid));
8781        } catch (RemoteException e) {
8782        } catch (IllegalArgumentException e) {
8783            Slog.w(TAG, "Failed trying to unstop package "
8784                    + info.packageName + ": " + e);
8785        }
8786
8787        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
8788                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
8789            app.persistent = true;
8790            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
8791        }
8792        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
8793            mPersistentStartingProcesses.add(app);
8794            startProcessLocked(app, "added application", app.processName,
8795                    abiOverride);
8796        }
8797
8798        return app;
8799    }
8800
8801    public void unhandledBack() {
8802        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
8803                "unhandledBack()");
8804
8805        synchronized(this) {
8806            final long origId = Binder.clearCallingIdentity();
8807            try {
8808                getFocusedStack().unhandledBackLocked();
8809            } finally {
8810                Binder.restoreCallingIdentity(origId);
8811            }
8812        }
8813    }
8814
8815    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
8816        enforceNotIsolatedCaller("openContentUri");
8817        final int userId = UserHandle.getCallingUserId();
8818        String name = uri.getAuthority();
8819        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
8820        ParcelFileDescriptor pfd = null;
8821        if (cph != null) {
8822            // We record the binder invoker's uid in thread-local storage before
8823            // going to the content provider to open the file.  Later, in the code
8824            // that handles all permissions checks, we look for this uid and use
8825            // that rather than the Activity Manager's own uid.  The effect is that
8826            // we do the check against the caller's permissions even though it looks
8827            // to the content provider like the Activity Manager itself is making
8828            // the request.
8829            sCallerIdentity.set(new Identity(
8830                    Binder.getCallingPid(), Binder.getCallingUid()));
8831            try {
8832                pfd = cph.provider.openFile(null, uri, "r", null);
8833            } catch (FileNotFoundException e) {
8834                // do nothing; pfd will be returned null
8835            } finally {
8836                // Ensure that whatever happens, we clean up the identity state
8837                sCallerIdentity.remove();
8838            }
8839
8840            // We've got the fd now, so we're done with the provider.
8841            removeContentProviderExternalUnchecked(name, null, userId);
8842        } else {
8843            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
8844        }
8845        return pfd;
8846    }
8847
8848    // Actually is sleeping or shutting down or whatever else in the future
8849    // is an inactive state.
8850    public boolean isSleepingOrShuttingDown() {
8851        return mSleeping || mShuttingDown;
8852    }
8853
8854    public boolean isSleeping() {
8855        return mSleeping;
8856    }
8857
8858    void goingToSleep() {
8859        synchronized(this) {
8860            mWentToSleep = true;
8861            updateEventDispatchingLocked();
8862            goToSleepIfNeededLocked();
8863        }
8864    }
8865
8866    void finishRunningVoiceLocked() {
8867        if (mRunningVoice) {
8868            mRunningVoice = false;
8869            goToSleepIfNeededLocked();
8870        }
8871    }
8872
8873    void goToSleepIfNeededLocked() {
8874        if (mWentToSleep && !mRunningVoice) {
8875            if (!mSleeping) {
8876                mSleeping = true;
8877                mStackSupervisor.goingToSleepLocked();
8878
8879                // Initialize the wake times of all processes.
8880                checkExcessivePowerUsageLocked(false);
8881                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8882                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
8883                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
8884            }
8885        }
8886    }
8887
8888    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
8889        mTaskPersister.notify(task, flush);
8890    }
8891
8892    @Override
8893    public boolean shutdown(int timeout) {
8894        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
8895                != PackageManager.PERMISSION_GRANTED) {
8896            throw new SecurityException("Requires permission "
8897                    + android.Manifest.permission.SHUTDOWN);
8898        }
8899
8900        boolean timedout = false;
8901
8902        synchronized(this) {
8903            mShuttingDown = true;
8904            updateEventDispatchingLocked();
8905            timedout = mStackSupervisor.shutdownLocked(timeout);
8906        }
8907
8908        mAppOpsService.shutdown();
8909        mUsageStatsService.shutdown();
8910        mBatteryStatsService.shutdown();
8911        synchronized (this) {
8912            mProcessStats.shutdownLocked();
8913        }
8914        notifyTaskPersisterLocked(null, true);
8915
8916        return timedout;
8917    }
8918
8919    public final void activitySlept(IBinder token) {
8920        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
8921
8922        final long origId = Binder.clearCallingIdentity();
8923
8924        synchronized (this) {
8925            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
8926            if (r != null) {
8927                mStackSupervisor.activitySleptLocked(r);
8928            }
8929        }
8930
8931        Binder.restoreCallingIdentity(origId);
8932    }
8933
8934    void logLockScreen(String msg) {
8935        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
8936                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
8937                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
8938                mStackSupervisor.mDismissKeyguardOnNextActivity);
8939    }
8940
8941    private void comeOutOfSleepIfNeededLocked() {
8942        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
8943            if (mSleeping) {
8944                mSleeping = false;
8945                mStackSupervisor.comeOutOfSleepIfNeededLocked();
8946            }
8947        }
8948    }
8949
8950    void wakingUp() {
8951        synchronized(this) {
8952            mWentToSleep = false;
8953            updateEventDispatchingLocked();
8954            comeOutOfSleepIfNeededLocked();
8955        }
8956    }
8957
8958    void startRunningVoiceLocked() {
8959        if (!mRunningVoice) {
8960            mRunningVoice = true;
8961            comeOutOfSleepIfNeededLocked();
8962        }
8963    }
8964
8965    private void updateEventDispatchingLocked() {
8966        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
8967    }
8968
8969    public void setLockScreenShown(boolean shown) {
8970        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
8971                != PackageManager.PERMISSION_GRANTED) {
8972            throw new SecurityException("Requires permission "
8973                    + android.Manifest.permission.DEVICE_POWER);
8974        }
8975
8976        synchronized(this) {
8977            long ident = Binder.clearCallingIdentity();
8978            try {
8979                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
8980                mLockScreenShown = shown;
8981                comeOutOfSleepIfNeededLocked();
8982            } finally {
8983                Binder.restoreCallingIdentity(ident);
8984            }
8985        }
8986    }
8987
8988    public void stopAppSwitches() {
8989        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
8990                != PackageManager.PERMISSION_GRANTED) {
8991            throw new SecurityException("Requires permission "
8992                    + android.Manifest.permission.STOP_APP_SWITCHES);
8993        }
8994
8995        synchronized(this) {
8996            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
8997                    + APP_SWITCH_DELAY_TIME;
8998            mDidAppSwitch = false;
8999            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9000            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9001            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9002        }
9003    }
9004
9005    public void resumeAppSwitches() {
9006        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9007                != PackageManager.PERMISSION_GRANTED) {
9008            throw new SecurityException("Requires permission "
9009                    + android.Manifest.permission.STOP_APP_SWITCHES);
9010        }
9011
9012        synchronized(this) {
9013            // Note that we don't execute any pending app switches... we will
9014            // let those wait until either the timeout, or the next start
9015            // activity request.
9016            mAppSwitchesAllowedTime = 0;
9017        }
9018    }
9019
9020    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9021            String name) {
9022        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9023            return true;
9024        }
9025
9026        final int perm = checkComponentPermission(
9027                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9028                callingUid, -1, true);
9029        if (perm == PackageManager.PERMISSION_GRANTED) {
9030            return true;
9031        }
9032
9033        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9034        return false;
9035    }
9036
9037    public void setDebugApp(String packageName, boolean waitForDebugger,
9038            boolean persistent) {
9039        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9040                "setDebugApp()");
9041
9042        long ident = Binder.clearCallingIdentity();
9043        try {
9044            // Note that this is not really thread safe if there are multiple
9045            // callers into it at the same time, but that's not a situation we
9046            // care about.
9047            if (persistent) {
9048                final ContentResolver resolver = mContext.getContentResolver();
9049                Settings.Global.putString(
9050                    resolver, Settings.Global.DEBUG_APP,
9051                    packageName);
9052                Settings.Global.putInt(
9053                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9054                    waitForDebugger ? 1 : 0);
9055            }
9056
9057            synchronized (this) {
9058                if (!persistent) {
9059                    mOrigDebugApp = mDebugApp;
9060                    mOrigWaitForDebugger = mWaitForDebugger;
9061                }
9062                mDebugApp = packageName;
9063                mWaitForDebugger = waitForDebugger;
9064                mDebugTransient = !persistent;
9065                if (packageName != null) {
9066                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9067                            false, UserHandle.USER_ALL, "set debug app");
9068                }
9069            }
9070        } finally {
9071            Binder.restoreCallingIdentity(ident);
9072        }
9073    }
9074
9075    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9076        synchronized (this) {
9077            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9078            if (!isDebuggable) {
9079                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9080                    throw new SecurityException("Process not debuggable: " + app.packageName);
9081                }
9082            }
9083
9084            mOpenGlTraceApp = processName;
9085        }
9086    }
9087
9088    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9089            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
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            mProfileApp = processName;
9098            mProfileFile = profileFile;
9099            if (mProfileFd != null) {
9100                try {
9101                    mProfileFd.close();
9102                } catch (IOException e) {
9103                }
9104                mProfileFd = null;
9105            }
9106            mProfileFd = profileFd;
9107            mProfileType = 0;
9108            mAutoStopProfiler = autoStopProfiler;
9109        }
9110    }
9111
9112    @Override
9113    public void setAlwaysFinish(boolean enabled) {
9114        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9115                "setAlwaysFinish()");
9116
9117        Settings.Global.putInt(
9118                mContext.getContentResolver(),
9119                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9120
9121        synchronized (this) {
9122            mAlwaysFinishActivities = enabled;
9123        }
9124    }
9125
9126    @Override
9127    public void setActivityController(IActivityController controller) {
9128        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9129                "setActivityController()");
9130        synchronized (this) {
9131            mController = controller;
9132            Watchdog.getInstance().setActivityController(controller);
9133        }
9134    }
9135
9136    @Override
9137    public void setUserIsMonkey(boolean userIsMonkey) {
9138        synchronized (this) {
9139            synchronized (mPidsSelfLocked) {
9140                final int callingPid = Binder.getCallingPid();
9141                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9142                if (precessRecord == null) {
9143                    throw new SecurityException("Unknown process: " + callingPid);
9144                }
9145                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9146                    throw new SecurityException("Only an instrumentation process "
9147                            + "with a UiAutomation can call setUserIsMonkey");
9148                }
9149            }
9150            mUserIsMonkey = userIsMonkey;
9151        }
9152    }
9153
9154    @Override
9155    public boolean isUserAMonkey() {
9156        synchronized (this) {
9157            // If there is a controller also implies the user is a monkey.
9158            return (mUserIsMonkey || mController != null);
9159        }
9160    }
9161
9162    public void requestBugReport() {
9163        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9164        SystemProperties.set("ctl.start", "bugreport");
9165    }
9166
9167    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9168        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9169    }
9170
9171    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9172        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9173            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9174        }
9175        return KEY_DISPATCHING_TIMEOUT;
9176    }
9177
9178    @Override
9179    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9180        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9181                != PackageManager.PERMISSION_GRANTED) {
9182            throw new SecurityException("Requires permission "
9183                    + android.Manifest.permission.FILTER_EVENTS);
9184        }
9185        ProcessRecord proc;
9186        long timeout;
9187        synchronized (this) {
9188            synchronized (mPidsSelfLocked) {
9189                proc = mPidsSelfLocked.get(pid);
9190            }
9191            timeout = getInputDispatchingTimeoutLocked(proc);
9192        }
9193
9194        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9195            return -1;
9196        }
9197
9198        return timeout;
9199    }
9200
9201    /**
9202     * Handle input dispatching timeouts.
9203     * Returns whether input dispatching should be aborted or not.
9204     */
9205    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9206            final ActivityRecord activity, final ActivityRecord parent,
9207            final boolean aboveSystem, String reason) {
9208        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9209                != PackageManager.PERMISSION_GRANTED) {
9210            throw new SecurityException("Requires permission "
9211                    + android.Manifest.permission.FILTER_EVENTS);
9212        }
9213
9214        final String annotation;
9215        if (reason == null) {
9216            annotation = "Input dispatching timed out";
9217        } else {
9218            annotation = "Input dispatching timed out (" + reason + ")";
9219        }
9220
9221        if (proc != null) {
9222            synchronized (this) {
9223                if (proc.debugging) {
9224                    return false;
9225                }
9226
9227                if (mDidDexOpt) {
9228                    // Give more time since we were dexopting.
9229                    mDidDexOpt = false;
9230                    return false;
9231                }
9232
9233                if (proc.instrumentationClass != null) {
9234                    Bundle info = new Bundle();
9235                    info.putString("shortMsg", "keyDispatchingTimedOut");
9236                    info.putString("longMsg", annotation);
9237                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9238                    return true;
9239                }
9240            }
9241            mHandler.post(new Runnable() {
9242                @Override
9243                public void run() {
9244                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9245                }
9246            });
9247        }
9248
9249        return true;
9250    }
9251
9252    public Bundle getAssistContextExtras(int requestType) {
9253        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9254                "getAssistContextExtras()");
9255        PendingAssistExtras pae;
9256        Bundle extras = new Bundle();
9257        synchronized (this) {
9258            ActivityRecord activity = getFocusedStack().mResumedActivity;
9259            if (activity == null) {
9260                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9261                return null;
9262            }
9263            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9264            if (activity.app == null || activity.app.thread == null) {
9265                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9266                return extras;
9267            }
9268            if (activity.app.pid == Binder.getCallingPid()) {
9269                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9270                return extras;
9271            }
9272            pae = new PendingAssistExtras(activity);
9273            try {
9274                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9275                        requestType);
9276                mPendingAssistExtras.add(pae);
9277                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9278            } catch (RemoteException e) {
9279                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9280                return extras;
9281            }
9282        }
9283        synchronized (pae) {
9284            while (!pae.haveResult) {
9285                try {
9286                    pae.wait();
9287                } catch (InterruptedException e) {
9288                }
9289            }
9290            if (pae.result != null) {
9291                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9292            }
9293        }
9294        synchronized (this) {
9295            mPendingAssistExtras.remove(pae);
9296            mHandler.removeCallbacks(pae);
9297        }
9298        return extras;
9299    }
9300
9301    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9302        PendingAssistExtras pae = (PendingAssistExtras)token;
9303        synchronized (pae) {
9304            pae.result = extras;
9305            pae.haveResult = true;
9306            pae.notifyAll();
9307        }
9308    }
9309
9310    public void registerProcessObserver(IProcessObserver observer) {
9311        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9312                "registerProcessObserver()");
9313        synchronized (this) {
9314            mProcessObservers.register(observer);
9315        }
9316    }
9317
9318    @Override
9319    public void unregisterProcessObserver(IProcessObserver observer) {
9320        synchronized (this) {
9321            mProcessObservers.unregister(observer);
9322        }
9323    }
9324
9325    @Override
9326    public boolean convertFromTranslucent(IBinder token) {
9327        final long origId = Binder.clearCallingIdentity();
9328        try {
9329            synchronized (this) {
9330                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9331                if (r == null) {
9332                    return false;
9333                }
9334                if (r.changeWindowTranslucency(true)) {
9335                    mWindowManager.setAppFullscreen(token, true);
9336                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9337                    return true;
9338                }
9339                return false;
9340            }
9341        } finally {
9342            Binder.restoreCallingIdentity(origId);
9343        }
9344    }
9345
9346    @Override
9347    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9348        final long origId = Binder.clearCallingIdentity();
9349        try {
9350            synchronized (this) {
9351                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9352                if (r == null) {
9353                    return false;
9354                }
9355                if (r.changeWindowTranslucency(false)) {
9356                    r.task.stack.convertToTranslucent(r, options);
9357                    mWindowManager.setAppFullscreen(token, false);
9358                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9359                    return true;
9360                }
9361                return false;
9362            }
9363        } finally {
9364            Binder.restoreCallingIdentity(origId);
9365        }
9366    }
9367
9368    @Override
9369    public ActivityOptions getActivityOptions(IBinder token) {
9370        final long origId = Binder.clearCallingIdentity();
9371        try {
9372            synchronized (this) {
9373                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9374                if (r != null) {
9375                    final ActivityOptions activityOptions = r.pendingOptions;
9376                    r.pendingOptions = null;
9377                    return activityOptions;
9378                }
9379                return null;
9380            }
9381        } finally {
9382            Binder.restoreCallingIdentity(origId);
9383        }
9384    }
9385
9386    @Override
9387    public void setImmersive(IBinder token, boolean immersive) {
9388        synchronized(this) {
9389            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9390            if (r == null) {
9391                throw new IllegalArgumentException();
9392            }
9393            r.immersive = immersive;
9394
9395            // update associated state if we're frontmost
9396            if (r == mFocusedActivity) {
9397                if (DEBUG_IMMERSIVE) {
9398                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9399                }
9400                applyUpdateLockStateLocked(r);
9401            }
9402        }
9403    }
9404
9405    @Override
9406    public boolean isImmersive(IBinder token) {
9407        synchronized (this) {
9408            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9409            if (r == null) {
9410                throw new IllegalArgumentException();
9411            }
9412            return r.immersive;
9413        }
9414    }
9415
9416    public boolean isTopActivityImmersive() {
9417        enforceNotIsolatedCaller("startActivity");
9418        synchronized (this) {
9419            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9420            return (r != null) ? r.immersive : false;
9421        }
9422    }
9423
9424    public final void enterSafeMode() {
9425        synchronized(this) {
9426            // It only makes sense to do this before the system is ready
9427            // and started launching other packages.
9428            if (!mSystemReady) {
9429                try {
9430                    AppGlobals.getPackageManager().enterSafeMode();
9431                } catch (RemoteException e) {
9432                }
9433            }
9434
9435            mSafeMode = true;
9436        }
9437    }
9438
9439    public final void showSafeModeOverlay() {
9440        View v = LayoutInflater.from(mContext).inflate(
9441                com.android.internal.R.layout.safe_mode, null);
9442        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9443        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9444        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9445        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9446        lp.gravity = Gravity.BOTTOM | Gravity.START;
9447        lp.format = v.getBackground().getOpacity();
9448        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9449                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9450        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9451        ((WindowManager)mContext.getSystemService(
9452                Context.WINDOW_SERVICE)).addView(v, lp);
9453    }
9454
9455    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9456        if (!(sender instanceof PendingIntentRecord)) {
9457            return;
9458        }
9459        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9460        synchronized (stats) {
9461            if (mBatteryStatsService.isOnBattery()) {
9462                mBatteryStatsService.enforceCallingPermission();
9463                PendingIntentRecord rec = (PendingIntentRecord)sender;
9464                int MY_UID = Binder.getCallingUid();
9465                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9466                BatteryStatsImpl.Uid.Pkg pkg =
9467                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9468                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9469                pkg.incWakeupsLocked();
9470            }
9471        }
9472    }
9473
9474    public boolean killPids(int[] pids, String pReason, boolean secure) {
9475        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9476            throw new SecurityException("killPids only available to the system");
9477        }
9478        String reason = (pReason == null) ? "Unknown" : pReason;
9479        // XXX Note: don't acquire main activity lock here, because the window
9480        // manager calls in with its locks held.
9481
9482        boolean killed = false;
9483        synchronized (mPidsSelfLocked) {
9484            int[] types = new int[pids.length];
9485            int worstType = 0;
9486            for (int i=0; i<pids.length; i++) {
9487                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9488                if (proc != null) {
9489                    int type = proc.setAdj;
9490                    types[i] = type;
9491                    if (type > worstType) {
9492                        worstType = type;
9493                    }
9494                }
9495            }
9496
9497            // If the worst oom_adj is somewhere in the cached proc LRU range,
9498            // then constrain it so we will kill all cached procs.
9499            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9500                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9501                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9502            }
9503
9504            // If this is not a secure call, don't let it kill processes that
9505            // are important.
9506            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9507                worstType = ProcessList.SERVICE_ADJ;
9508            }
9509
9510            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9511            for (int i=0; i<pids.length; i++) {
9512                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9513                if (proc == null) {
9514                    continue;
9515                }
9516                int adj = proc.setAdj;
9517                if (adj >= worstType && !proc.killedByAm) {
9518                    killUnneededProcessLocked(proc, reason);
9519                    killed = true;
9520                }
9521            }
9522        }
9523        return killed;
9524    }
9525
9526    @Override
9527    public void killUid(int uid, String reason) {
9528        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9529            throw new SecurityException("killUid only available to the system");
9530        }
9531        synchronized (this) {
9532            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9533                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9534                    reason != null ? reason : "kill uid");
9535        }
9536    }
9537
9538    @Override
9539    public boolean killProcessesBelowForeground(String reason) {
9540        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9541            throw new SecurityException("killProcessesBelowForeground() only available to system");
9542        }
9543
9544        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9545    }
9546
9547    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9548        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9549            throw new SecurityException("killProcessesBelowAdj() only available to system");
9550        }
9551
9552        boolean killed = false;
9553        synchronized (mPidsSelfLocked) {
9554            final int size = mPidsSelfLocked.size();
9555            for (int i = 0; i < size; i++) {
9556                final int pid = mPidsSelfLocked.keyAt(i);
9557                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9558                if (proc == null) continue;
9559
9560                final int adj = proc.setAdj;
9561                if (adj > belowAdj && !proc.killedByAm) {
9562                    killUnneededProcessLocked(proc, reason);
9563                    killed = true;
9564                }
9565            }
9566        }
9567        return killed;
9568    }
9569
9570    @Override
9571    public void hang(final IBinder who, boolean allowRestart) {
9572        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9573                != PackageManager.PERMISSION_GRANTED) {
9574            throw new SecurityException("Requires permission "
9575                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9576        }
9577
9578        final IBinder.DeathRecipient death = new DeathRecipient() {
9579            @Override
9580            public void binderDied() {
9581                synchronized (this) {
9582                    notifyAll();
9583                }
9584            }
9585        };
9586
9587        try {
9588            who.linkToDeath(death, 0);
9589        } catch (RemoteException e) {
9590            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9591            return;
9592        }
9593
9594        synchronized (this) {
9595            Watchdog.getInstance().setAllowRestart(allowRestart);
9596            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9597            synchronized (death) {
9598                while (who.isBinderAlive()) {
9599                    try {
9600                        death.wait();
9601                    } catch (InterruptedException e) {
9602                    }
9603                }
9604            }
9605            Watchdog.getInstance().setAllowRestart(true);
9606        }
9607    }
9608
9609    @Override
9610    public void restart() {
9611        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9612                != PackageManager.PERMISSION_GRANTED) {
9613            throw new SecurityException("Requires permission "
9614                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9615        }
9616
9617        Log.i(TAG, "Sending shutdown broadcast...");
9618
9619        BroadcastReceiver br = new BroadcastReceiver() {
9620            @Override public void onReceive(Context context, Intent intent) {
9621                // Now the broadcast is done, finish up the low-level shutdown.
9622                Log.i(TAG, "Shutting down activity manager...");
9623                shutdown(10000);
9624                Log.i(TAG, "Shutdown complete, restarting!");
9625                Process.killProcess(Process.myPid());
9626                System.exit(10);
9627            }
9628        };
9629
9630        // First send the high-level shut down broadcast.
9631        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9632        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9633        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9634        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9635        mContext.sendOrderedBroadcastAsUser(intent,
9636                UserHandle.ALL, null, br, mHandler, 0, null, null);
9637        */
9638        br.onReceive(mContext, intent);
9639    }
9640
9641    private long getLowRamTimeSinceIdle(long now) {
9642        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9643    }
9644
9645    @Override
9646    public void performIdleMaintenance() {
9647        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9648                != PackageManager.PERMISSION_GRANTED) {
9649            throw new SecurityException("Requires permission "
9650                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9651        }
9652
9653        synchronized (this) {
9654            final long now = SystemClock.uptimeMillis();
9655            final long timeSinceLastIdle = now - mLastIdleTime;
9656            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9657            mLastIdleTime = now;
9658            mLowRamTimeSinceLastIdle = 0;
9659            if (mLowRamStartTime != 0) {
9660                mLowRamStartTime = now;
9661            }
9662
9663            StringBuilder sb = new StringBuilder(128);
9664            sb.append("Idle maintenance over ");
9665            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9666            sb.append(" low RAM for ");
9667            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9668            Slog.i(TAG, sb.toString());
9669
9670            // If at least 1/3 of our time since the last idle period has been spent
9671            // with RAM low, then we want to kill processes.
9672            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9673
9674            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9675                ProcessRecord proc = mLruProcesses.get(i);
9676                if (proc.notCachedSinceIdle) {
9677                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9678                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9679                        if (doKilling && proc.initialIdlePss != 0
9680                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9681                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9682                                    + " from " + proc.initialIdlePss + ")");
9683                        }
9684                    }
9685                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
9686                    proc.notCachedSinceIdle = true;
9687                    proc.initialIdlePss = 0;
9688                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
9689                            isSleeping(), now);
9690                }
9691            }
9692
9693            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
9694            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
9695        }
9696    }
9697
9698    private void retrieveSettings() {
9699        final ContentResolver resolver = mContext.getContentResolver();
9700        String debugApp = Settings.Global.getString(
9701            resolver, Settings.Global.DEBUG_APP);
9702        boolean waitForDebugger = Settings.Global.getInt(
9703            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
9704        boolean alwaysFinishActivities = Settings.Global.getInt(
9705            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
9706        boolean forceRtl = Settings.Global.getInt(
9707                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
9708        // Transfer any global setting for forcing RTL layout, into a System Property
9709        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
9710
9711        Configuration configuration = new Configuration();
9712        Settings.System.getConfiguration(resolver, configuration);
9713        if (forceRtl) {
9714            // This will take care of setting the correct layout direction flags
9715            configuration.setLayoutDirection(configuration.locale);
9716        }
9717
9718        synchronized (this) {
9719            mDebugApp = mOrigDebugApp = debugApp;
9720            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
9721            mAlwaysFinishActivities = alwaysFinishActivities;
9722            // This happens before any activities are started, so we can
9723            // change mConfiguration in-place.
9724            updateConfigurationLocked(configuration, null, false, true);
9725            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
9726        }
9727    }
9728
9729    public boolean testIsSystemReady() {
9730        // no need to synchronize(this) just to read & return the value
9731        return mSystemReady;
9732    }
9733
9734    private static File getCalledPreBootReceiversFile() {
9735        File dataDir = Environment.getDataDirectory();
9736        File systemDir = new File(dataDir, "system");
9737        File fname = new File(systemDir, "called_pre_boots.dat");
9738        return fname;
9739    }
9740
9741    static final int LAST_DONE_VERSION = 10000;
9742
9743    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
9744        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
9745        File file = getCalledPreBootReceiversFile();
9746        FileInputStream fis = null;
9747        try {
9748            fis = new FileInputStream(file);
9749            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
9750            int fvers = dis.readInt();
9751            if (fvers == LAST_DONE_VERSION) {
9752                String vers = dis.readUTF();
9753                String codename = dis.readUTF();
9754                String build = dis.readUTF();
9755                if (android.os.Build.VERSION.RELEASE.equals(vers)
9756                        && android.os.Build.VERSION.CODENAME.equals(codename)
9757                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
9758                    int num = dis.readInt();
9759                    while (num > 0) {
9760                        num--;
9761                        String pkg = dis.readUTF();
9762                        String cls = dis.readUTF();
9763                        lastDoneReceivers.add(new ComponentName(pkg, cls));
9764                    }
9765                }
9766            }
9767        } catch (FileNotFoundException e) {
9768        } catch (IOException e) {
9769            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
9770        } finally {
9771            if (fis != null) {
9772                try {
9773                    fis.close();
9774                } catch (IOException e) {
9775                }
9776            }
9777        }
9778        return lastDoneReceivers;
9779    }
9780
9781    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
9782        File file = getCalledPreBootReceiversFile();
9783        FileOutputStream fos = null;
9784        DataOutputStream dos = null;
9785        try {
9786            Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
9787            fos = new FileOutputStream(file);
9788            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
9789            dos.writeInt(LAST_DONE_VERSION);
9790            dos.writeUTF(android.os.Build.VERSION.RELEASE);
9791            dos.writeUTF(android.os.Build.VERSION.CODENAME);
9792            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
9793            dos.writeInt(list.size());
9794            for (int i=0; i<list.size(); i++) {
9795                dos.writeUTF(list.get(i).getPackageName());
9796                dos.writeUTF(list.get(i).getClassName());
9797            }
9798        } catch (IOException e) {
9799            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
9800            file.delete();
9801        } finally {
9802            FileUtils.sync(fos);
9803            if (dos != null) {
9804                try {
9805                    dos.close();
9806                } catch (IOException e) {
9807                    // TODO Auto-generated catch block
9808                    e.printStackTrace();
9809                }
9810            }
9811        }
9812    }
9813
9814    public void systemReady(final Runnable goingCallback) {
9815        synchronized(this) {
9816            if (mSystemReady) {
9817                if (goingCallback != null) goingCallback.run();
9818                return;
9819            }
9820
9821            if (mRecentTasks == null) {
9822                mRecentTasks = mTaskPersister.restoreTasksLocked();
9823                if (!mRecentTasks.isEmpty()) {
9824                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
9825                }
9826                mTaskPersister.startPersisting();
9827            }
9828
9829            // Check to see if there are any update receivers to run.
9830            if (!mDidUpdate) {
9831                if (mWaitingUpdate) {
9832                    return;
9833                }
9834                Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
9835                List<ResolveInfo> ris = null;
9836                try {
9837                    ris = AppGlobals.getPackageManager().queryIntentReceivers(
9838                            intent, null, 0, 0);
9839                } catch (RemoteException e) {
9840                }
9841                if (ris != null) {
9842                    for (int i=ris.size()-1; i>=0; i--) {
9843                        if ((ris.get(i).activityInfo.applicationInfo.flags
9844                                &ApplicationInfo.FLAG_SYSTEM) == 0) {
9845                            ris.remove(i);
9846                        }
9847                    }
9848                    intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
9849
9850                    ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
9851
9852                    final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
9853                    for (int i=0; i<ris.size(); i++) {
9854                        ActivityInfo ai = ris.get(i).activityInfo;
9855                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9856                        if (lastDoneReceivers.contains(comp)) {
9857                            // We already did the pre boot receiver for this app with the current
9858                            // platform version, so don't do it again...
9859                            ris.remove(i);
9860                            i--;
9861                            // ...however, do keep it as one that has been done, so we don't
9862                            // forget about it when rewriting the file of last done receivers.
9863                            doneReceivers.add(comp);
9864                        }
9865                    }
9866
9867                    final int[] users = getUsersLocked();
9868                    for (int i=0; i<ris.size(); i++) {
9869                        ActivityInfo ai = ris.get(i).activityInfo;
9870                        ComponentName comp = new ComponentName(ai.packageName, ai.name);
9871                        doneReceivers.add(comp);
9872                        intent.setComponent(comp);
9873                        for (int j=0; j<users.length; j++) {
9874                            IIntentReceiver finisher = null;
9875                            if (i == ris.size()-1 && j == users.length-1) {
9876                                finisher = new IIntentReceiver.Stub() {
9877                                    public void performReceive(Intent intent, int resultCode,
9878                                            String data, Bundle extras, boolean ordered,
9879                                            boolean sticky, int sendingUser) {
9880                                        // The raw IIntentReceiver interface is called
9881                                        // with the AM lock held, so redispatch to
9882                                        // execute our code without the lock.
9883                                        mHandler.post(new Runnable() {
9884                                            public void run() {
9885                                                synchronized (ActivityManagerService.this) {
9886                                                    mDidUpdate = true;
9887                                                }
9888                                                writeLastDonePreBootReceivers(doneReceivers);
9889                                                showBootMessage(mContext.getText(
9890                                                        R.string.android_upgrading_complete),
9891                                                        false);
9892                                                systemReady(goingCallback);
9893                                            }
9894                                        });
9895                                    }
9896                                };
9897                            }
9898                            Slog.i(TAG, "Sending system update to " + intent.getComponent()
9899                                    + " for user " + users[j]);
9900                            broadcastIntentLocked(null, null, intent, null, finisher,
9901                                    0, null, null, null, AppOpsManager.OP_NONE,
9902                                    true, false, MY_PID, Process.SYSTEM_UID,
9903                                    users[j]);
9904                            if (finisher != null) {
9905                                mWaitingUpdate = true;
9906                            }
9907                        }
9908                    }
9909                }
9910                if (mWaitingUpdate) {
9911                    return;
9912                }
9913                mDidUpdate = true;
9914            }
9915
9916            mAppOpsService.systemReady();
9917            mUsageStatsService.systemReady();
9918            mSystemReady = true;
9919        }
9920
9921        ArrayList<ProcessRecord> procsToKill = null;
9922        synchronized(mPidsSelfLocked) {
9923            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
9924                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9925                if (!isAllowedWhileBooting(proc.info)){
9926                    if (procsToKill == null) {
9927                        procsToKill = new ArrayList<ProcessRecord>();
9928                    }
9929                    procsToKill.add(proc);
9930                }
9931            }
9932        }
9933
9934        synchronized(this) {
9935            if (procsToKill != null) {
9936                for (int i=procsToKill.size()-1; i>=0; i--) {
9937                    ProcessRecord proc = procsToKill.get(i);
9938                    Slog.i(TAG, "Removing system update proc: " + proc);
9939                    removeProcessLocked(proc, true, false, "system update done");
9940                }
9941            }
9942
9943            // Now that we have cleaned up any update processes, we
9944            // are ready to start launching real processes and know that
9945            // we won't trample on them any more.
9946            mProcessesReady = true;
9947        }
9948
9949        Slog.i(TAG, "System now ready");
9950        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
9951            SystemClock.uptimeMillis());
9952
9953        synchronized(this) {
9954            // Make sure we have no pre-ready processes sitting around.
9955
9956            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
9957                ResolveInfo ri = mContext.getPackageManager()
9958                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
9959                                STOCK_PM_FLAGS);
9960                CharSequence errorMsg = null;
9961                if (ri != null) {
9962                    ActivityInfo ai = ri.activityInfo;
9963                    ApplicationInfo app = ai.applicationInfo;
9964                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
9965                        mTopAction = Intent.ACTION_FACTORY_TEST;
9966                        mTopData = null;
9967                        mTopComponent = new ComponentName(app.packageName,
9968                                ai.name);
9969                    } else {
9970                        errorMsg = mContext.getResources().getText(
9971                                com.android.internal.R.string.factorytest_not_system);
9972                    }
9973                } else {
9974                    errorMsg = mContext.getResources().getText(
9975                            com.android.internal.R.string.factorytest_no_action);
9976                }
9977                if (errorMsg != null) {
9978                    mTopAction = null;
9979                    mTopData = null;
9980                    mTopComponent = null;
9981                    Message msg = Message.obtain();
9982                    msg.what = SHOW_FACTORY_ERROR_MSG;
9983                    msg.getData().putCharSequence("msg", errorMsg);
9984                    mHandler.sendMessage(msg);
9985                }
9986            }
9987        }
9988
9989        retrieveSettings();
9990
9991        synchronized (this) {
9992            readGrantedUriPermissionsLocked();
9993        }
9994
9995        if (goingCallback != null) goingCallback.run();
9996
9997        mSystemServiceManager.startUser(mCurrentUserId);
9998
9999        synchronized (this) {
10000            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10001                try {
10002                    List apps = AppGlobals.getPackageManager().
10003                        getPersistentApplications(STOCK_PM_FLAGS);
10004                    if (apps != null) {
10005                        int N = apps.size();
10006                        int i;
10007                        for (i=0; i<N; i++) {
10008                            ApplicationInfo info
10009                                = (ApplicationInfo)apps.get(i);
10010                            if (info != null &&
10011                                    !info.packageName.equals("android")) {
10012                                addAppLocked(info, false, null /* ABI override */);
10013                            }
10014                        }
10015                    }
10016                } catch (RemoteException ex) {
10017                    // pm is in same process, this will never happen.
10018                }
10019            }
10020
10021            // Start up initial activity.
10022            mBooting = true;
10023
10024            try {
10025                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10026                    Message msg = Message.obtain();
10027                    msg.what = SHOW_UID_ERROR_MSG;
10028                    mHandler.sendMessage(msg);
10029                }
10030            } catch (RemoteException e) {
10031            }
10032
10033            long ident = Binder.clearCallingIdentity();
10034            try {
10035                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10036                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10037                        | Intent.FLAG_RECEIVER_FOREGROUND);
10038                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10039                broadcastIntentLocked(null, null, intent,
10040                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10041                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10042                intent = new Intent(Intent.ACTION_USER_STARTING);
10043                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10044                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10045                broadcastIntentLocked(null, null, intent,
10046                        null, new IIntentReceiver.Stub() {
10047                            @Override
10048                            public void performReceive(Intent intent, int resultCode, String data,
10049                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10050                                    throws RemoteException {
10051                            }
10052                        }, 0, null, null,
10053                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10054                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10055            } catch (Throwable t) {
10056                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10057            } finally {
10058                Binder.restoreCallingIdentity(ident);
10059            }
10060            mStackSupervisor.resumeTopActivitiesLocked();
10061            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10062        }
10063    }
10064
10065    private boolean makeAppCrashingLocked(ProcessRecord app,
10066            String shortMsg, String longMsg, String stackTrace) {
10067        app.crashing = true;
10068        app.crashingReport = generateProcessError(app,
10069                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10070        startAppProblemLocked(app);
10071        app.stopFreezingAllLocked();
10072        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10073    }
10074
10075    private void makeAppNotRespondingLocked(ProcessRecord app,
10076            String activity, String shortMsg, String longMsg) {
10077        app.notResponding = true;
10078        app.notRespondingReport = generateProcessError(app,
10079                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10080                activity, shortMsg, longMsg, null);
10081        startAppProblemLocked(app);
10082        app.stopFreezingAllLocked();
10083    }
10084
10085    /**
10086     * Generate a process error record, suitable for attachment to a ProcessRecord.
10087     *
10088     * @param app The ProcessRecord in which the error occurred.
10089     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10090     *                      ActivityManager.AppErrorStateInfo
10091     * @param activity The activity associated with the crash, if known.
10092     * @param shortMsg Short message describing the crash.
10093     * @param longMsg Long message describing the crash.
10094     * @param stackTrace Full crash stack trace, may be null.
10095     *
10096     * @return Returns a fully-formed AppErrorStateInfo record.
10097     */
10098    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10099            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10100        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10101
10102        report.condition = condition;
10103        report.processName = app.processName;
10104        report.pid = app.pid;
10105        report.uid = app.info.uid;
10106        report.tag = activity;
10107        report.shortMsg = shortMsg;
10108        report.longMsg = longMsg;
10109        report.stackTrace = stackTrace;
10110
10111        return report;
10112    }
10113
10114    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10115        synchronized (this) {
10116            app.crashing = false;
10117            app.crashingReport = null;
10118            app.notResponding = false;
10119            app.notRespondingReport = null;
10120            if (app.anrDialog == fromDialog) {
10121                app.anrDialog = null;
10122            }
10123            if (app.waitDialog == fromDialog) {
10124                app.waitDialog = null;
10125            }
10126            if (app.pid > 0 && app.pid != MY_PID) {
10127                handleAppCrashLocked(app, null, null, null);
10128                killUnneededProcessLocked(app, "user request after error");
10129            }
10130        }
10131    }
10132
10133    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10134            String stackTrace) {
10135        long now = SystemClock.uptimeMillis();
10136
10137        Long crashTime;
10138        if (!app.isolated) {
10139            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10140        } else {
10141            crashTime = null;
10142        }
10143        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10144            // This process loses!
10145            Slog.w(TAG, "Process " + app.info.processName
10146                    + " has crashed too many times: killing!");
10147            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10148                    app.userId, app.info.processName, app.uid);
10149            mStackSupervisor.handleAppCrashLocked(app);
10150            if (!app.persistent) {
10151                // We don't want to start this process again until the user
10152                // explicitly does so...  but for persistent process, we really
10153                // need to keep it running.  If a persistent process is actually
10154                // repeatedly crashing, then badness for everyone.
10155                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10156                        app.info.processName);
10157                if (!app.isolated) {
10158                    // XXX We don't have a way to mark isolated processes
10159                    // as bad, since they don't have a peristent identity.
10160                    mBadProcesses.put(app.info.processName, app.uid,
10161                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10162                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10163                }
10164                app.bad = true;
10165                app.removed = true;
10166                // Don't let services in this process be restarted and potentially
10167                // annoy the user repeatedly.  Unless it is persistent, since those
10168                // processes run critical code.
10169                removeProcessLocked(app, false, false, "crash");
10170                mStackSupervisor.resumeTopActivitiesLocked();
10171                return false;
10172            }
10173            mStackSupervisor.resumeTopActivitiesLocked();
10174        } else {
10175            mStackSupervisor.finishTopRunningActivityLocked(app);
10176        }
10177
10178        // Bump up the crash count of any services currently running in the proc.
10179        for (int i=app.services.size()-1; i>=0; i--) {
10180            // Any services running in the application need to be placed
10181            // back in the pending list.
10182            ServiceRecord sr = app.services.valueAt(i);
10183            sr.crashCount++;
10184        }
10185
10186        // If the crashing process is what we consider to be the "home process" and it has been
10187        // replaced by a third-party app, clear the package preferred activities from packages
10188        // with a home activity running in the process to prevent a repeatedly crashing app
10189        // from blocking the user to manually clear the list.
10190        final ArrayList<ActivityRecord> activities = app.activities;
10191        if (app == mHomeProcess && activities.size() > 0
10192                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10193            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10194                final ActivityRecord r = activities.get(activityNdx);
10195                if (r.isHomeActivity()) {
10196                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10197                    try {
10198                        ActivityThread.getPackageManager()
10199                                .clearPackagePreferredActivities(r.packageName);
10200                    } catch (RemoteException c) {
10201                        // pm is in same process, this will never happen.
10202                    }
10203                }
10204            }
10205        }
10206
10207        if (!app.isolated) {
10208            // XXX Can't keep track of crash times for isolated processes,
10209            // because they don't have a perisistent identity.
10210            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10211        }
10212
10213        return true;
10214    }
10215
10216    void startAppProblemLocked(ProcessRecord app) {
10217        if (app.userId == mCurrentUserId) {
10218            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10219                    mContext, app.info.packageName, app.info.flags);
10220        } else {
10221            // If this app is not running under the current user, then we
10222            // can't give it a report button because that would require
10223            // launching the report UI under a different user.
10224            app.errorReportReceiver = null;
10225        }
10226        skipCurrentReceiverLocked(app);
10227    }
10228
10229    void skipCurrentReceiverLocked(ProcessRecord app) {
10230        for (BroadcastQueue queue : mBroadcastQueues) {
10231            queue.skipCurrentReceiverLocked(app);
10232        }
10233    }
10234
10235    /**
10236     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10237     * The application process will exit immediately after this call returns.
10238     * @param app object of the crashing app, null for the system server
10239     * @param crashInfo describing the exception
10240     */
10241    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10242        ProcessRecord r = findAppProcess(app, "Crash");
10243        final String processName = app == null ? "system_server"
10244                : (r == null ? "unknown" : r.processName);
10245
10246        handleApplicationCrashInner("crash", r, processName, crashInfo);
10247    }
10248
10249    /* Native crash reporting uses this inner version because it needs to be somewhat
10250     * decoupled from the AM-managed cleanup lifecycle
10251     */
10252    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10253            ApplicationErrorReport.CrashInfo crashInfo) {
10254        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10255                UserHandle.getUserId(Binder.getCallingUid()), processName,
10256                r == null ? -1 : r.info.flags,
10257                crashInfo.exceptionClassName,
10258                crashInfo.exceptionMessage,
10259                crashInfo.throwFileName,
10260                crashInfo.throwLineNumber);
10261
10262        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10263
10264        crashApplication(r, crashInfo);
10265    }
10266
10267    public void handleApplicationStrictModeViolation(
10268            IBinder app,
10269            int violationMask,
10270            StrictMode.ViolationInfo info) {
10271        ProcessRecord r = findAppProcess(app, "StrictMode");
10272        if (r == null) {
10273            return;
10274        }
10275
10276        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10277            Integer stackFingerprint = info.hashCode();
10278            boolean logIt = true;
10279            synchronized (mAlreadyLoggedViolatedStacks) {
10280                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10281                    logIt = false;
10282                    // TODO: sub-sample into EventLog for these, with
10283                    // the info.durationMillis?  Then we'd get
10284                    // the relative pain numbers, without logging all
10285                    // the stack traces repeatedly.  We'd want to do
10286                    // likewise in the client code, which also does
10287                    // dup suppression, before the Binder call.
10288                } else {
10289                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10290                        mAlreadyLoggedViolatedStacks.clear();
10291                    }
10292                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10293                }
10294            }
10295            if (logIt) {
10296                logStrictModeViolationToDropBox(r, info);
10297            }
10298        }
10299
10300        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10301            AppErrorResult result = new AppErrorResult();
10302            synchronized (this) {
10303                final long origId = Binder.clearCallingIdentity();
10304
10305                Message msg = Message.obtain();
10306                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10307                HashMap<String, Object> data = new HashMap<String, Object>();
10308                data.put("result", result);
10309                data.put("app", r);
10310                data.put("violationMask", violationMask);
10311                data.put("info", info);
10312                msg.obj = data;
10313                mHandler.sendMessage(msg);
10314
10315                Binder.restoreCallingIdentity(origId);
10316            }
10317            int res = result.get();
10318            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10319        }
10320    }
10321
10322    // Depending on the policy in effect, there could be a bunch of
10323    // these in quick succession so we try to batch these together to
10324    // minimize disk writes, number of dropbox entries, and maximize
10325    // compression, by having more fewer, larger records.
10326    private void logStrictModeViolationToDropBox(
10327            ProcessRecord process,
10328            StrictMode.ViolationInfo info) {
10329        if (info == null) {
10330            return;
10331        }
10332        final boolean isSystemApp = process == null ||
10333                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10334                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10335        final String processName = process == null ? "unknown" : process.processName;
10336        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10337        final DropBoxManager dbox = (DropBoxManager)
10338                mContext.getSystemService(Context.DROPBOX_SERVICE);
10339
10340        // Exit early if the dropbox isn't configured to accept this report type.
10341        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10342
10343        boolean bufferWasEmpty;
10344        boolean needsFlush;
10345        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10346        synchronized (sb) {
10347            bufferWasEmpty = sb.length() == 0;
10348            appendDropBoxProcessHeaders(process, processName, sb);
10349            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10350            sb.append("System-App: ").append(isSystemApp).append("\n");
10351            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10352            if (info.violationNumThisLoop != 0) {
10353                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10354            }
10355            if (info.numAnimationsRunning != 0) {
10356                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10357            }
10358            if (info.broadcastIntentAction != null) {
10359                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10360            }
10361            if (info.durationMillis != -1) {
10362                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10363            }
10364            if (info.numInstances != -1) {
10365                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10366            }
10367            if (info.tags != null) {
10368                for (String tag : info.tags) {
10369                    sb.append("Span-Tag: ").append(tag).append("\n");
10370                }
10371            }
10372            sb.append("\n");
10373            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10374                sb.append(info.crashInfo.stackTrace);
10375            }
10376            sb.append("\n");
10377
10378            // Only buffer up to ~64k.  Various logging bits truncate
10379            // things at 128k.
10380            needsFlush = (sb.length() > 64 * 1024);
10381        }
10382
10383        // Flush immediately if the buffer's grown too large, or this
10384        // is a non-system app.  Non-system apps are isolated with a
10385        // different tag & policy and not batched.
10386        //
10387        // Batching is useful during internal testing with
10388        // StrictMode settings turned up high.  Without batching,
10389        // thousands of separate files could be created on boot.
10390        if (!isSystemApp || needsFlush) {
10391            new Thread("Error dump: " + dropboxTag) {
10392                @Override
10393                public void run() {
10394                    String report;
10395                    synchronized (sb) {
10396                        report = sb.toString();
10397                        sb.delete(0, sb.length());
10398                        sb.trimToSize();
10399                    }
10400                    if (report.length() != 0) {
10401                        dbox.addText(dropboxTag, report);
10402                    }
10403                }
10404            }.start();
10405            return;
10406        }
10407
10408        // System app batching:
10409        if (!bufferWasEmpty) {
10410            // An existing dropbox-writing thread is outstanding, so
10411            // we don't need to start it up.  The existing thread will
10412            // catch the buffer appends we just did.
10413            return;
10414        }
10415
10416        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10417        // (After this point, we shouldn't access AMS internal data structures.)
10418        new Thread("Error dump: " + dropboxTag) {
10419            @Override
10420            public void run() {
10421                // 5 second sleep to let stacks arrive and be batched together
10422                try {
10423                    Thread.sleep(5000);  // 5 seconds
10424                } catch (InterruptedException e) {}
10425
10426                String errorReport;
10427                synchronized (mStrictModeBuffer) {
10428                    errorReport = mStrictModeBuffer.toString();
10429                    if (errorReport.length() == 0) {
10430                        return;
10431                    }
10432                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10433                    mStrictModeBuffer.trimToSize();
10434                }
10435                dbox.addText(dropboxTag, errorReport);
10436            }
10437        }.start();
10438    }
10439
10440    /**
10441     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10442     * @param app object of the crashing app, null for the system server
10443     * @param tag reported by the caller
10444     * @param crashInfo describing the context of the error
10445     * @return true if the process should exit immediately (WTF is fatal)
10446     */
10447    public boolean handleApplicationWtf(IBinder app, String tag,
10448            ApplicationErrorReport.CrashInfo crashInfo) {
10449        ProcessRecord r = findAppProcess(app, "WTF");
10450        final String processName = app == null ? "system_server"
10451                : (r == null ? "unknown" : r.processName);
10452
10453        EventLog.writeEvent(EventLogTags.AM_WTF,
10454                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10455                processName,
10456                r == null ? -1 : r.info.flags,
10457                tag, crashInfo.exceptionMessage);
10458
10459        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10460
10461        if (r != null && r.pid != Process.myPid() &&
10462                Settings.Global.getInt(mContext.getContentResolver(),
10463                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10464            crashApplication(r, crashInfo);
10465            return true;
10466        } else {
10467            return false;
10468        }
10469    }
10470
10471    /**
10472     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10473     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10474     */
10475    private ProcessRecord findAppProcess(IBinder app, String reason) {
10476        if (app == null) {
10477            return null;
10478        }
10479
10480        synchronized (this) {
10481            final int NP = mProcessNames.getMap().size();
10482            for (int ip=0; ip<NP; ip++) {
10483                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10484                final int NA = apps.size();
10485                for (int ia=0; ia<NA; ia++) {
10486                    ProcessRecord p = apps.valueAt(ia);
10487                    if (p.thread != null && p.thread.asBinder() == app) {
10488                        return p;
10489                    }
10490                }
10491            }
10492
10493            Slog.w(TAG, "Can't find mystery application for " + reason
10494                    + " from pid=" + Binder.getCallingPid()
10495                    + " uid=" + Binder.getCallingUid() + ": " + app);
10496            return null;
10497        }
10498    }
10499
10500    /**
10501     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10502     * to append various headers to the dropbox log text.
10503     */
10504    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10505            StringBuilder sb) {
10506        // Watchdog thread ends up invoking this function (with
10507        // a null ProcessRecord) to add the stack file to dropbox.
10508        // Do not acquire a lock on this (am) in such cases, as it
10509        // could cause a potential deadlock, if and when watchdog
10510        // is invoked due to unavailability of lock on am and it
10511        // would prevent watchdog from killing system_server.
10512        if (process == null) {
10513            sb.append("Process: ").append(processName).append("\n");
10514            return;
10515        }
10516        // Note: ProcessRecord 'process' is guarded by the service
10517        // instance.  (notably process.pkgList, which could otherwise change
10518        // concurrently during execution of this method)
10519        synchronized (this) {
10520            sb.append("Process: ").append(processName).append("\n");
10521            int flags = process.info.flags;
10522            IPackageManager pm = AppGlobals.getPackageManager();
10523            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10524            for (int ip=0; ip<process.pkgList.size(); ip++) {
10525                String pkg = process.pkgList.keyAt(ip);
10526                sb.append("Package: ").append(pkg);
10527                try {
10528                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10529                    if (pi != null) {
10530                        sb.append(" v").append(pi.versionCode);
10531                        if (pi.versionName != null) {
10532                            sb.append(" (").append(pi.versionName).append(")");
10533                        }
10534                    }
10535                } catch (RemoteException e) {
10536                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10537                }
10538                sb.append("\n");
10539            }
10540        }
10541    }
10542
10543    private static String processClass(ProcessRecord process) {
10544        if (process == null || process.pid == MY_PID) {
10545            return "system_server";
10546        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10547            return "system_app";
10548        } else {
10549            return "data_app";
10550        }
10551    }
10552
10553    /**
10554     * Write a description of an error (crash, WTF, ANR) to the drop box.
10555     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10556     * @param process which caused the error, null means the system server
10557     * @param activity which triggered the error, null if unknown
10558     * @param parent activity related to the error, null if unknown
10559     * @param subject line related to the error, null if absent
10560     * @param report in long form describing the error, null if absent
10561     * @param logFile to include in the report, null if none
10562     * @param crashInfo giving an application stack trace, null if absent
10563     */
10564    public void addErrorToDropBox(String eventType,
10565            ProcessRecord process, String processName, ActivityRecord activity,
10566            ActivityRecord parent, String subject,
10567            final String report, final File logFile,
10568            final ApplicationErrorReport.CrashInfo crashInfo) {
10569        // NOTE -- this must never acquire the ActivityManagerService lock,
10570        // otherwise the watchdog may be prevented from resetting the system.
10571
10572        final String dropboxTag = processClass(process) + "_" + eventType;
10573        final DropBoxManager dbox = (DropBoxManager)
10574                mContext.getSystemService(Context.DROPBOX_SERVICE);
10575
10576        // Exit early if the dropbox isn't configured to accept this report type.
10577        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10578
10579        final StringBuilder sb = new StringBuilder(1024);
10580        appendDropBoxProcessHeaders(process, processName, sb);
10581        if (activity != null) {
10582            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10583        }
10584        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10585            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10586        }
10587        if (parent != null && parent != activity) {
10588            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10589        }
10590        if (subject != null) {
10591            sb.append("Subject: ").append(subject).append("\n");
10592        }
10593        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10594        if (Debug.isDebuggerConnected()) {
10595            sb.append("Debugger: Connected\n");
10596        }
10597        sb.append("\n");
10598
10599        // Do the rest in a worker thread to avoid blocking the caller on I/O
10600        // (After this point, we shouldn't access AMS internal data structures.)
10601        Thread worker = new Thread("Error dump: " + dropboxTag) {
10602            @Override
10603            public void run() {
10604                if (report != null) {
10605                    sb.append(report);
10606                }
10607                if (logFile != null) {
10608                    try {
10609                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10610                                    "\n\n[[TRUNCATED]]"));
10611                    } catch (IOException e) {
10612                        Slog.e(TAG, "Error reading " + logFile, e);
10613                    }
10614                }
10615                if (crashInfo != null && crashInfo.stackTrace != null) {
10616                    sb.append(crashInfo.stackTrace);
10617                }
10618
10619                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10620                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10621                if (lines > 0) {
10622                    sb.append("\n");
10623
10624                    // Merge several logcat streams, and take the last N lines
10625                    InputStreamReader input = null;
10626                    try {
10627                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10628                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10629                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10630
10631                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10632                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10633                        input = new InputStreamReader(logcat.getInputStream());
10634
10635                        int num;
10636                        char[] buf = new char[8192];
10637                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10638                    } catch (IOException e) {
10639                        Slog.e(TAG, "Error running logcat", e);
10640                    } finally {
10641                        if (input != null) try { input.close(); } catch (IOException e) {}
10642                    }
10643                }
10644
10645                dbox.addText(dropboxTag, sb.toString());
10646            }
10647        };
10648
10649        if (process == null) {
10650            // If process is null, we are being called from some internal code
10651            // and may be about to die -- run this synchronously.
10652            worker.run();
10653        } else {
10654            worker.start();
10655        }
10656    }
10657
10658    /**
10659     * Bring up the "unexpected error" dialog box for a crashing app.
10660     * Deal with edge cases (intercepts from instrumented applications,
10661     * ActivityController, error intent receivers, that sort of thing).
10662     * @param r the application crashing
10663     * @param crashInfo describing the failure
10664     */
10665    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
10666        long timeMillis = System.currentTimeMillis();
10667        String shortMsg = crashInfo.exceptionClassName;
10668        String longMsg = crashInfo.exceptionMessage;
10669        String stackTrace = crashInfo.stackTrace;
10670        if (shortMsg != null && longMsg != null) {
10671            longMsg = shortMsg + ": " + longMsg;
10672        } else if (shortMsg != null) {
10673            longMsg = shortMsg;
10674        }
10675
10676        AppErrorResult result = new AppErrorResult();
10677        synchronized (this) {
10678            if (mController != null) {
10679                try {
10680                    String name = r != null ? r.processName : null;
10681                    int pid = r != null ? r.pid : Binder.getCallingPid();
10682                    if (!mController.appCrashed(name, pid,
10683                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
10684                        Slog.w(TAG, "Force-killing crashed app " + name
10685                                + " at watcher's request");
10686                        Process.killProcess(pid);
10687                        return;
10688                    }
10689                } catch (RemoteException e) {
10690                    mController = null;
10691                    Watchdog.getInstance().setActivityController(null);
10692                }
10693            }
10694
10695            final long origId = Binder.clearCallingIdentity();
10696
10697            // If this process is running instrumentation, finish it.
10698            if (r != null && r.instrumentationClass != null) {
10699                Slog.w(TAG, "Error in app " + r.processName
10700                      + " running instrumentation " + r.instrumentationClass + ":");
10701                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
10702                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
10703                Bundle info = new Bundle();
10704                info.putString("shortMsg", shortMsg);
10705                info.putString("longMsg", longMsg);
10706                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
10707                Binder.restoreCallingIdentity(origId);
10708                return;
10709            }
10710
10711            // If we can't identify the process or it's already exceeded its crash quota,
10712            // quit right away without showing a crash dialog.
10713            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
10714                Binder.restoreCallingIdentity(origId);
10715                return;
10716            }
10717
10718            Message msg = Message.obtain();
10719            msg.what = SHOW_ERROR_MSG;
10720            HashMap data = new HashMap();
10721            data.put("result", result);
10722            data.put("app", r);
10723            msg.obj = data;
10724            mHandler.sendMessage(msg);
10725
10726            Binder.restoreCallingIdentity(origId);
10727        }
10728
10729        int res = result.get();
10730
10731        Intent appErrorIntent = null;
10732        synchronized (this) {
10733            if (r != null && !r.isolated) {
10734                // XXX Can't keep track of crash time for isolated processes,
10735                // since they don't have a persistent identity.
10736                mProcessCrashTimes.put(r.info.processName, r.uid,
10737                        SystemClock.uptimeMillis());
10738            }
10739            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
10740                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
10741            }
10742        }
10743
10744        if (appErrorIntent != null) {
10745            try {
10746                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
10747            } catch (ActivityNotFoundException e) {
10748                Slog.w(TAG, "bug report receiver dissappeared", e);
10749            }
10750        }
10751    }
10752
10753    Intent createAppErrorIntentLocked(ProcessRecord r,
10754            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10755        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
10756        if (report == null) {
10757            return null;
10758        }
10759        Intent result = new Intent(Intent.ACTION_APP_ERROR);
10760        result.setComponent(r.errorReportReceiver);
10761        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
10762        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
10763        return result;
10764    }
10765
10766    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
10767            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
10768        if (r.errorReportReceiver == null) {
10769            return null;
10770        }
10771
10772        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
10773            return null;
10774        }
10775
10776        ApplicationErrorReport report = new ApplicationErrorReport();
10777        report.packageName = r.info.packageName;
10778        report.installerPackageName = r.errorReportReceiver.getPackageName();
10779        report.processName = r.processName;
10780        report.time = timeMillis;
10781        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
10782
10783        if (r.crashing || r.forceCrashReport) {
10784            report.type = ApplicationErrorReport.TYPE_CRASH;
10785            report.crashInfo = crashInfo;
10786        } else if (r.notResponding) {
10787            report.type = ApplicationErrorReport.TYPE_ANR;
10788            report.anrInfo = new ApplicationErrorReport.AnrInfo();
10789
10790            report.anrInfo.activity = r.notRespondingReport.tag;
10791            report.anrInfo.cause = r.notRespondingReport.shortMsg;
10792            report.anrInfo.info = r.notRespondingReport.longMsg;
10793        }
10794
10795        return report;
10796    }
10797
10798    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
10799        enforceNotIsolatedCaller("getProcessesInErrorState");
10800        // assume our apps are happy - lazy create the list
10801        List<ActivityManager.ProcessErrorStateInfo> errList = null;
10802
10803        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10804                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10805        int userId = UserHandle.getUserId(Binder.getCallingUid());
10806
10807        synchronized (this) {
10808
10809            // iterate across all processes
10810            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10811                ProcessRecord app = mLruProcesses.get(i);
10812                if (!allUsers && app.userId != userId) {
10813                    continue;
10814                }
10815                if ((app.thread != null) && (app.crashing || app.notResponding)) {
10816                    // This one's in trouble, so we'll generate a report for it
10817                    // crashes are higher priority (in case there's a crash *and* an anr)
10818                    ActivityManager.ProcessErrorStateInfo report = null;
10819                    if (app.crashing) {
10820                        report = app.crashingReport;
10821                    } else if (app.notResponding) {
10822                        report = app.notRespondingReport;
10823                    }
10824
10825                    if (report != null) {
10826                        if (errList == null) {
10827                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
10828                        }
10829                        errList.add(report);
10830                    } else {
10831                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
10832                                " crashing = " + app.crashing +
10833                                " notResponding = " + app.notResponding);
10834                    }
10835                }
10836            }
10837        }
10838
10839        return errList;
10840    }
10841
10842    static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
10843        if (adj >= ProcessList.CACHED_APP_MIN_ADJ) {
10844            if (currApp != null) {
10845                currApp.lru = adj - ProcessList.CACHED_APP_MIN_ADJ + 1;
10846            }
10847            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10848        } else if (adj >= ProcessList.SERVICE_B_ADJ) {
10849            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10850        } else if (adj >= ProcessList.HOME_APP_ADJ) {
10851            if (currApp != null) {
10852                currApp.lru = 0;
10853            }
10854            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
10855        } else if (adj >= ProcessList.SERVICE_ADJ) {
10856            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
10857        } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10858            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
10859        } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10860            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
10861        } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
10862            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
10863        } else {
10864            return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
10865        }
10866    }
10867
10868    private void fillInProcMemInfo(ProcessRecord app,
10869            ActivityManager.RunningAppProcessInfo outInfo) {
10870        outInfo.pid = app.pid;
10871        outInfo.uid = app.info.uid;
10872        if (mHeavyWeightProcess == app) {
10873            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
10874        }
10875        if (app.persistent) {
10876            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
10877        }
10878        if (app.activities.size() > 0) {
10879            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
10880        }
10881        outInfo.lastTrimLevel = app.trimMemoryLevel;
10882        int adj = app.curAdj;
10883        outInfo.importance = oomAdjToImportance(adj, outInfo);
10884        outInfo.importanceReasonCode = app.adjTypeCode;
10885        outInfo.processState = app.curProcState;
10886    }
10887
10888    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
10889        enforceNotIsolatedCaller("getRunningAppProcesses");
10890        // Lazy instantiation of list
10891        List<ActivityManager.RunningAppProcessInfo> runList = null;
10892        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
10893                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
10894        int userId = UserHandle.getUserId(Binder.getCallingUid());
10895        synchronized (this) {
10896            // Iterate across all processes
10897            for (int i=mLruProcesses.size()-1; i>=0; i--) {
10898                ProcessRecord app = mLruProcesses.get(i);
10899                if (!allUsers && app.userId != userId) {
10900                    continue;
10901                }
10902                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
10903                    // Generate process state info for running application
10904                    ActivityManager.RunningAppProcessInfo currApp =
10905                        new ActivityManager.RunningAppProcessInfo(app.processName,
10906                                app.pid, app.getPackageList());
10907                    fillInProcMemInfo(app, currApp);
10908                    if (app.adjSource instanceof ProcessRecord) {
10909                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
10910                        currApp.importanceReasonImportance = oomAdjToImportance(
10911                                app.adjSourceOom, null);
10912                    } else if (app.adjSource instanceof ActivityRecord) {
10913                        ActivityRecord r = (ActivityRecord)app.adjSource;
10914                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
10915                    }
10916                    if (app.adjTarget instanceof ComponentName) {
10917                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
10918                    }
10919                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
10920                    //        + " lru=" + currApp.lru);
10921                    if (runList == null) {
10922                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
10923                    }
10924                    runList.add(currApp);
10925                }
10926            }
10927        }
10928        return runList;
10929    }
10930
10931    public List<ApplicationInfo> getRunningExternalApplications() {
10932        enforceNotIsolatedCaller("getRunningExternalApplications");
10933        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
10934        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
10935        if (runningApps != null && runningApps.size() > 0) {
10936            Set<String> extList = new HashSet<String>();
10937            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
10938                if (app.pkgList != null) {
10939                    for (String pkg : app.pkgList) {
10940                        extList.add(pkg);
10941                    }
10942                }
10943            }
10944            IPackageManager pm = AppGlobals.getPackageManager();
10945            for (String pkg : extList) {
10946                try {
10947                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
10948                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
10949                        retList.add(info);
10950                    }
10951                } catch (RemoteException e) {
10952                }
10953            }
10954        }
10955        return retList;
10956    }
10957
10958    @Override
10959    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
10960        enforceNotIsolatedCaller("getMyMemoryState");
10961        synchronized (this) {
10962            ProcessRecord proc;
10963            synchronized (mPidsSelfLocked) {
10964                proc = mPidsSelfLocked.get(Binder.getCallingPid());
10965            }
10966            fillInProcMemInfo(proc, outInfo);
10967        }
10968    }
10969
10970    @Override
10971    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
10972        if (checkCallingPermission(android.Manifest.permission.DUMP)
10973                != PackageManager.PERMISSION_GRANTED) {
10974            pw.println("Permission Denial: can't dump ActivityManager from from pid="
10975                    + Binder.getCallingPid()
10976                    + ", uid=" + Binder.getCallingUid()
10977                    + " without permission "
10978                    + android.Manifest.permission.DUMP);
10979            return;
10980        }
10981
10982        boolean dumpAll = false;
10983        boolean dumpClient = false;
10984        String dumpPackage = null;
10985
10986        int opti = 0;
10987        while (opti < args.length) {
10988            String opt = args[opti];
10989            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10990                break;
10991            }
10992            opti++;
10993            if ("-a".equals(opt)) {
10994                dumpAll = true;
10995            } else if ("-c".equals(opt)) {
10996                dumpClient = true;
10997            } else if ("-h".equals(opt)) {
10998                pw.println("Activity manager dump options:");
10999                pw.println("  [-a] [-c] [-h] [cmd] ...");
11000                pw.println("  cmd may be one of:");
11001                pw.println("    a[ctivities]: activity stack state");
11002                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11003                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11004                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11005                pw.println("    o[om]: out of memory management");
11006                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11007                pw.println("    provider [COMP_SPEC]: provider client-side state");
11008                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11009                pw.println("    service [COMP_SPEC]: service client-side state");
11010                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11011                pw.println("    all: dump all activities");
11012                pw.println("    top: dump the top activity");
11013                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11014                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11015                pw.println("    a partial substring in a component name, a");
11016                pw.println("    hex object identifier.");
11017                pw.println("  -a: include all available server state.");
11018                pw.println("  -c: include client state.");
11019                return;
11020            } else {
11021                pw.println("Unknown argument: " + opt + "; use -h for help");
11022            }
11023        }
11024
11025        long origId = Binder.clearCallingIdentity();
11026        boolean more = false;
11027        // Is the caller requesting to dump a particular piece of data?
11028        if (opti < args.length) {
11029            String cmd = args[opti];
11030            opti++;
11031            if ("activities".equals(cmd) || "a".equals(cmd)) {
11032                synchronized (this) {
11033                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11034                }
11035            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11036                String[] newArgs;
11037                String name;
11038                if (opti >= args.length) {
11039                    name = null;
11040                    newArgs = EMPTY_STRING_ARRAY;
11041                } else {
11042                    name = args[opti];
11043                    opti++;
11044                    newArgs = new String[args.length - opti];
11045                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11046                            args.length - opti);
11047                }
11048                synchronized (this) {
11049                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11050                }
11051            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11052                String[] newArgs;
11053                String name;
11054                if (opti >= args.length) {
11055                    name = null;
11056                    newArgs = EMPTY_STRING_ARRAY;
11057                } else {
11058                    name = args[opti];
11059                    opti++;
11060                    newArgs = new String[args.length - opti];
11061                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11062                            args.length - opti);
11063                }
11064                synchronized (this) {
11065                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11066                }
11067            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11068                String[] newArgs;
11069                String name;
11070                if (opti >= args.length) {
11071                    name = null;
11072                    newArgs = EMPTY_STRING_ARRAY;
11073                } else {
11074                    name = args[opti];
11075                    opti++;
11076                    newArgs = new String[args.length - opti];
11077                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11078                            args.length - opti);
11079                }
11080                synchronized (this) {
11081                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11082                }
11083            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11084                synchronized (this) {
11085                    dumpOomLocked(fd, pw, args, opti, true);
11086                }
11087            } else if ("provider".equals(cmd)) {
11088                String[] newArgs;
11089                String name;
11090                if (opti >= args.length) {
11091                    name = null;
11092                    newArgs = EMPTY_STRING_ARRAY;
11093                } else {
11094                    name = args[opti];
11095                    opti++;
11096                    newArgs = new String[args.length - opti];
11097                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11098                }
11099                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11100                    pw.println("No providers match: " + name);
11101                    pw.println("Use -h for help.");
11102                }
11103            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11104                synchronized (this) {
11105                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11106                }
11107            } else if ("service".equals(cmd)) {
11108                String[] newArgs;
11109                String name;
11110                if (opti >= args.length) {
11111                    name = null;
11112                    newArgs = EMPTY_STRING_ARRAY;
11113                } else {
11114                    name = args[opti];
11115                    opti++;
11116                    newArgs = new String[args.length - opti];
11117                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11118                            args.length - opti);
11119                }
11120                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11121                    pw.println("No services match: " + name);
11122                    pw.println("Use -h for help.");
11123                }
11124            } else if ("package".equals(cmd)) {
11125                String[] newArgs;
11126                if (opti >= args.length) {
11127                    pw.println("package: no package name specified");
11128                    pw.println("Use -h for help.");
11129                } else {
11130                    dumpPackage = args[opti];
11131                    opti++;
11132                    newArgs = new String[args.length - opti];
11133                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11134                            args.length - opti);
11135                    args = newArgs;
11136                    opti = 0;
11137                    more = true;
11138                }
11139            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11140                synchronized (this) {
11141                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11142                }
11143            } else {
11144                // Dumping a single activity?
11145                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11146                    pw.println("Bad activity command, or no activities match: " + cmd);
11147                    pw.println("Use -h for help.");
11148                }
11149            }
11150            if (!more) {
11151                Binder.restoreCallingIdentity(origId);
11152                return;
11153            }
11154        }
11155
11156        // No piece of data specified, dump everything.
11157        synchronized (this) {
11158            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11159            pw.println();
11160            if (dumpAll) {
11161                pw.println("-------------------------------------------------------------------------------");
11162            }
11163            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11164            pw.println();
11165            if (dumpAll) {
11166                pw.println("-------------------------------------------------------------------------------");
11167            }
11168            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11169            pw.println();
11170            if (dumpAll) {
11171                pw.println("-------------------------------------------------------------------------------");
11172            }
11173            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11174            pw.println();
11175            if (dumpAll) {
11176                pw.println("-------------------------------------------------------------------------------");
11177            }
11178            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11179            pw.println();
11180            if (dumpAll) {
11181                pw.println("-------------------------------------------------------------------------------");
11182            }
11183            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11184        }
11185        Binder.restoreCallingIdentity(origId);
11186    }
11187
11188    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11189            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11190        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11191
11192        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11193                dumpPackage);
11194        boolean needSep = printedAnything;
11195
11196        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11197                dumpPackage, needSep, "  mFocusedActivity: ");
11198        if (printed) {
11199            printedAnything = true;
11200            needSep = false;
11201        }
11202
11203        if (dumpPackage == null) {
11204            if (needSep) {
11205                pw.println();
11206            }
11207            needSep = true;
11208            printedAnything = true;
11209            mStackSupervisor.dump(pw, "  ");
11210        }
11211
11212        if (mRecentTasks.size() > 0) {
11213            boolean printedHeader = false;
11214
11215            final int N = mRecentTasks.size();
11216            for (int i=0; i<N; i++) {
11217                TaskRecord tr = mRecentTasks.get(i);
11218                if (dumpPackage != null) {
11219                    if (tr.realActivity == null ||
11220                            !dumpPackage.equals(tr.realActivity)) {
11221                        continue;
11222                    }
11223                }
11224                if (!printedHeader) {
11225                    if (needSep) {
11226                        pw.println();
11227                    }
11228                    pw.println("  Recent tasks:");
11229                    printedHeader = true;
11230                    printedAnything = true;
11231                }
11232                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11233                        pw.println(tr);
11234                if (dumpAll) {
11235                    mRecentTasks.get(i).dump(pw, "    ");
11236                }
11237            }
11238        }
11239
11240        if (!printedAnything) {
11241            pw.println("  (nothing)");
11242        }
11243    }
11244
11245    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11246            int opti, boolean dumpAll, String dumpPackage) {
11247        boolean needSep = false;
11248        boolean printedAnything = false;
11249        int numPers = 0;
11250
11251        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11252
11253        if (dumpAll) {
11254            final int NP = mProcessNames.getMap().size();
11255            for (int ip=0; ip<NP; ip++) {
11256                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11257                final int NA = procs.size();
11258                for (int ia=0; ia<NA; ia++) {
11259                    ProcessRecord r = procs.valueAt(ia);
11260                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11261                        continue;
11262                    }
11263                    if (!needSep) {
11264                        pw.println("  All known processes:");
11265                        needSep = true;
11266                        printedAnything = true;
11267                    }
11268                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11269                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11270                        pw.print(" "); pw.println(r);
11271                    r.dump(pw, "    ");
11272                    if (r.persistent) {
11273                        numPers++;
11274                    }
11275                }
11276            }
11277        }
11278
11279        if (mIsolatedProcesses.size() > 0) {
11280            boolean printed = false;
11281            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11282                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11283                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11284                    continue;
11285                }
11286                if (!printed) {
11287                    if (needSep) {
11288                        pw.println();
11289                    }
11290                    pw.println("  Isolated process list (sorted by uid):");
11291                    printedAnything = true;
11292                    printed = true;
11293                    needSep = true;
11294                }
11295                pw.println(String.format("%sIsolated #%2d: %s",
11296                        "    ", i, r.toString()));
11297            }
11298        }
11299
11300        if (mLruProcesses.size() > 0) {
11301            if (needSep) {
11302                pw.println();
11303            }
11304            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11305                    pw.print(" total, non-act at ");
11306                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11307                    pw.print(", non-svc at ");
11308                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11309                    pw.println("):");
11310            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11311            needSep = true;
11312            printedAnything = true;
11313        }
11314
11315        if (dumpAll || dumpPackage != null) {
11316            synchronized (mPidsSelfLocked) {
11317                boolean printed = false;
11318                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11319                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11320                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11321                        continue;
11322                    }
11323                    if (!printed) {
11324                        if (needSep) pw.println();
11325                        needSep = true;
11326                        pw.println("  PID mappings:");
11327                        printed = true;
11328                        printedAnything = true;
11329                    }
11330                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11331                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11332                }
11333            }
11334        }
11335
11336        if (mForegroundProcesses.size() > 0) {
11337            synchronized (mPidsSelfLocked) {
11338                boolean printed = false;
11339                for (int i=0; i<mForegroundProcesses.size(); i++) {
11340                    ProcessRecord r = mPidsSelfLocked.get(
11341                            mForegroundProcesses.valueAt(i).pid);
11342                    if (dumpPackage != null && (r == null
11343                            || !r.pkgList.containsKey(dumpPackage))) {
11344                        continue;
11345                    }
11346                    if (!printed) {
11347                        if (needSep) pw.println();
11348                        needSep = true;
11349                        pw.println("  Foreground Processes:");
11350                        printed = true;
11351                        printedAnything = true;
11352                    }
11353                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11354                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11355                }
11356            }
11357        }
11358
11359        if (mPersistentStartingProcesses.size() > 0) {
11360            if (needSep) pw.println();
11361            needSep = true;
11362            printedAnything = true;
11363            pw.println("  Persisent processes that are starting:");
11364            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11365                    "Starting Norm", "Restarting PERS", dumpPackage);
11366        }
11367
11368        if (mRemovedProcesses.size() > 0) {
11369            if (needSep) pw.println();
11370            needSep = true;
11371            printedAnything = true;
11372            pw.println("  Processes that are being removed:");
11373            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11374                    "Removed Norm", "Removed PERS", dumpPackage);
11375        }
11376
11377        if (mProcessesOnHold.size() > 0) {
11378            if (needSep) pw.println();
11379            needSep = true;
11380            printedAnything = true;
11381            pw.println("  Processes that are on old until the system is ready:");
11382            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11383                    "OnHold Norm", "OnHold PERS", dumpPackage);
11384        }
11385
11386        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11387
11388        if (mProcessCrashTimes.getMap().size() > 0) {
11389            boolean printed = false;
11390            long now = SystemClock.uptimeMillis();
11391            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11392            final int NP = pmap.size();
11393            for (int ip=0; ip<NP; ip++) {
11394                String pname = pmap.keyAt(ip);
11395                SparseArray<Long> uids = pmap.valueAt(ip);
11396                final int N = uids.size();
11397                for (int i=0; i<N; i++) {
11398                    int puid = uids.keyAt(i);
11399                    ProcessRecord r = mProcessNames.get(pname, puid);
11400                    if (dumpPackage != null && (r == null
11401                            || !r.pkgList.containsKey(dumpPackage))) {
11402                        continue;
11403                    }
11404                    if (!printed) {
11405                        if (needSep) pw.println();
11406                        needSep = true;
11407                        pw.println("  Time since processes crashed:");
11408                        printed = true;
11409                        printedAnything = true;
11410                    }
11411                    pw.print("    Process "); pw.print(pname);
11412                            pw.print(" uid "); pw.print(puid);
11413                            pw.print(": last crashed ");
11414                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11415                            pw.println(" ago");
11416                }
11417            }
11418        }
11419
11420        if (mBadProcesses.getMap().size() > 0) {
11421            boolean printed = false;
11422            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11423            final int NP = pmap.size();
11424            for (int ip=0; ip<NP; ip++) {
11425                String pname = pmap.keyAt(ip);
11426                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11427                final int N = uids.size();
11428                for (int i=0; i<N; i++) {
11429                    int puid = uids.keyAt(i);
11430                    ProcessRecord r = mProcessNames.get(pname, puid);
11431                    if (dumpPackage != null && (r == null
11432                            || !r.pkgList.containsKey(dumpPackage))) {
11433                        continue;
11434                    }
11435                    if (!printed) {
11436                        if (needSep) pw.println();
11437                        needSep = true;
11438                        pw.println("  Bad processes:");
11439                        printedAnything = true;
11440                    }
11441                    BadProcessInfo info = uids.valueAt(i);
11442                    pw.print("    Bad process "); pw.print(pname);
11443                            pw.print(" uid "); pw.print(puid);
11444                            pw.print(": crashed at time "); pw.println(info.time);
11445                    if (info.shortMsg != null) {
11446                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11447                    }
11448                    if (info.longMsg != null) {
11449                        pw.print("      Long msg: "); pw.println(info.longMsg);
11450                    }
11451                    if (info.stack != null) {
11452                        pw.println("      Stack:");
11453                        int lastPos = 0;
11454                        for (int pos=0; pos<info.stack.length(); pos++) {
11455                            if (info.stack.charAt(pos) == '\n') {
11456                                pw.print("        ");
11457                                pw.write(info.stack, lastPos, pos-lastPos);
11458                                pw.println();
11459                                lastPos = pos+1;
11460                            }
11461                        }
11462                        if (lastPos < info.stack.length()) {
11463                            pw.print("        ");
11464                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11465                            pw.println();
11466                        }
11467                    }
11468                }
11469            }
11470        }
11471
11472        if (dumpPackage == null) {
11473            pw.println();
11474            needSep = false;
11475            pw.println("  mStartedUsers:");
11476            for (int i=0; i<mStartedUsers.size(); i++) {
11477                UserStartedState uss = mStartedUsers.valueAt(i);
11478                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11479                        pw.print(": "); uss.dump("", pw);
11480            }
11481            pw.print("  mStartedUserArray: [");
11482            for (int i=0; i<mStartedUserArray.length; i++) {
11483                if (i > 0) pw.print(", ");
11484                pw.print(mStartedUserArray[i]);
11485            }
11486            pw.println("]");
11487            pw.print("  mUserLru: [");
11488            for (int i=0; i<mUserLru.size(); i++) {
11489                if (i > 0) pw.print(", ");
11490                pw.print(mUserLru.get(i));
11491            }
11492            pw.println("]");
11493            if (dumpAll) {
11494                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11495            }
11496        }
11497        if (mHomeProcess != null && (dumpPackage == null
11498                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11499            if (needSep) {
11500                pw.println();
11501                needSep = false;
11502            }
11503            pw.println("  mHomeProcess: " + mHomeProcess);
11504        }
11505        if (mPreviousProcess != null && (dumpPackage == null
11506                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11507            if (needSep) {
11508                pw.println();
11509                needSep = false;
11510            }
11511            pw.println("  mPreviousProcess: " + mPreviousProcess);
11512        }
11513        if (dumpAll) {
11514            StringBuilder sb = new StringBuilder(128);
11515            sb.append("  mPreviousProcessVisibleTime: ");
11516            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11517            pw.println(sb);
11518        }
11519        if (mHeavyWeightProcess != null && (dumpPackage == null
11520                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11521            if (needSep) {
11522                pw.println();
11523                needSep = false;
11524            }
11525            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11526        }
11527        if (dumpPackage == null) {
11528            pw.println("  mConfiguration: " + mConfiguration);
11529        }
11530        if (dumpAll) {
11531            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11532            if (mCompatModePackages.getPackages().size() > 0) {
11533                boolean printed = false;
11534                for (Map.Entry<String, Integer> entry
11535                        : mCompatModePackages.getPackages().entrySet()) {
11536                    String pkg = entry.getKey();
11537                    int mode = entry.getValue();
11538                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11539                        continue;
11540                    }
11541                    if (!printed) {
11542                        pw.println("  mScreenCompatPackages:");
11543                        printed = true;
11544                    }
11545                    pw.print("    "); pw.print(pkg); pw.print(": ");
11546                            pw.print(mode); pw.println();
11547                }
11548            }
11549        }
11550        if (dumpPackage == null) {
11551            if (mSleeping || mWentToSleep || mLockScreenShown) {
11552                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11553                        + " mLockScreenShown " + mLockScreenShown);
11554            }
11555            if (mShuttingDown || mRunningVoice) {
11556                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11557            }
11558        }
11559        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11560                || mOrigWaitForDebugger) {
11561            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11562                    || dumpPackage.equals(mOrigDebugApp)) {
11563                if (needSep) {
11564                    pw.println();
11565                    needSep = false;
11566                }
11567                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11568                        + " mDebugTransient=" + mDebugTransient
11569                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11570            }
11571        }
11572        if (mOpenGlTraceApp != null) {
11573            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11574                if (needSep) {
11575                    pw.println();
11576                    needSep = false;
11577                }
11578                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11579            }
11580        }
11581        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11582                || mProfileFd != null) {
11583            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11584                if (needSep) {
11585                    pw.println();
11586                    needSep = false;
11587                }
11588                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11589                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11590                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11591                        + mAutoStopProfiler);
11592            }
11593        }
11594        if (dumpPackage == null) {
11595            if (mAlwaysFinishActivities || mController != null) {
11596                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11597                        + " mController=" + mController);
11598            }
11599            if (dumpAll) {
11600                pw.println("  Total persistent processes: " + numPers);
11601                pw.println("  mProcessesReady=" + mProcessesReady
11602                        + " mSystemReady=" + mSystemReady);
11603                pw.println("  mBooting=" + mBooting
11604                        + " mBooted=" + mBooted
11605                        + " mFactoryTest=" + mFactoryTest);
11606                pw.print("  mLastPowerCheckRealtime=");
11607                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11608                        pw.println("");
11609                pw.print("  mLastPowerCheckUptime=");
11610                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11611                        pw.println("");
11612                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11613                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11614                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11615                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11616                        + " (" + mLruProcesses.size() + " total)"
11617                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11618                        + " mNumServiceProcs=" + mNumServiceProcs
11619                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11620                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11621                        + " mLastMemoryLevel" + mLastMemoryLevel
11622                        + " mLastNumProcesses" + mLastNumProcesses);
11623                long now = SystemClock.uptimeMillis();
11624                pw.print("  mLastIdleTime=");
11625                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11626                        pw.print(" mLowRamSinceLastIdle=");
11627                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11628                        pw.println();
11629            }
11630        }
11631
11632        if (!printedAnything) {
11633            pw.println("  (nothing)");
11634        }
11635    }
11636
11637    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11638            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11639        if (mProcessesToGc.size() > 0) {
11640            boolean printed = false;
11641            long now = SystemClock.uptimeMillis();
11642            for (int i=0; i<mProcessesToGc.size(); i++) {
11643                ProcessRecord proc = mProcessesToGc.get(i);
11644                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11645                    continue;
11646                }
11647                if (!printed) {
11648                    if (needSep) pw.println();
11649                    needSep = true;
11650                    pw.println("  Processes that are waiting to GC:");
11651                    printed = true;
11652                }
11653                pw.print("    Process "); pw.println(proc);
11654                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
11655                        pw.print(", last gced=");
11656                        pw.print(now-proc.lastRequestedGc);
11657                        pw.print(" ms ago, last lowMem=");
11658                        pw.print(now-proc.lastLowMemory);
11659                        pw.println(" ms ago");
11660
11661            }
11662        }
11663        return needSep;
11664    }
11665
11666    void printOomLevel(PrintWriter pw, String name, int adj) {
11667        pw.print("    ");
11668        if (adj >= 0) {
11669            pw.print(' ');
11670            if (adj < 10) pw.print(' ');
11671        } else {
11672            if (adj > -10) pw.print(' ');
11673        }
11674        pw.print(adj);
11675        pw.print(": ");
11676        pw.print(name);
11677        pw.print(" (");
11678        pw.print(mProcessList.getMemLevel(adj)/1024);
11679        pw.println(" kB)");
11680    }
11681
11682    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11683            int opti, boolean dumpAll) {
11684        boolean needSep = false;
11685
11686        if (mLruProcesses.size() > 0) {
11687            if (needSep) pw.println();
11688            needSep = true;
11689            pw.println("  OOM levels:");
11690            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
11691            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
11692            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
11693            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
11694            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
11695            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
11696            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
11697            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
11698            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
11699            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
11700            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
11701            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
11702            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
11703
11704            if (needSep) pw.println();
11705            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
11706                    pw.print(" total, non-act at ");
11707                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11708                    pw.print(", non-svc at ");
11709                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11710                    pw.println("):");
11711            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
11712            needSep = true;
11713        }
11714
11715        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
11716
11717        pw.println();
11718        pw.println("  mHomeProcess: " + mHomeProcess);
11719        pw.println("  mPreviousProcess: " + mPreviousProcess);
11720        if (mHeavyWeightProcess != null) {
11721            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11722        }
11723
11724        return true;
11725    }
11726
11727    /**
11728     * There are three ways to call this:
11729     *  - no provider specified: dump all the providers
11730     *  - a flattened component name that matched an existing provider was specified as the
11731     *    first arg: dump that one provider
11732     *  - the first arg isn't the flattened component name of an existing provider:
11733     *    dump all providers whose component contains the first arg as a substring
11734     */
11735    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11736            int opti, boolean dumpAll) {
11737        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
11738    }
11739
11740    static class ItemMatcher {
11741        ArrayList<ComponentName> components;
11742        ArrayList<String> strings;
11743        ArrayList<Integer> objects;
11744        boolean all;
11745
11746        ItemMatcher() {
11747            all = true;
11748        }
11749
11750        void build(String name) {
11751            ComponentName componentName = ComponentName.unflattenFromString(name);
11752            if (componentName != null) {
11753                if (components == null) {
11754                    components = new ArrayList<ComponentName>();
11755                }
11756                components.add(componentName);
11757                all = false;
11758            } else {
11759                int objectId = 0;
11760                // Not a '/' separated full component name; maybe an object ID?
11761                try {
11762                    objectId = Integer.parseInt(name, 16);
11763                    if (objects == null) {
11764                        objects = new ArrayList<Integer>();
11765                    }
11766                    objects.add(objectId);
11767                    all = false;
11768                } catch (RuntimeException e) {
11769                    // Not an integer; just do string match.
11770                    if (strings == null) {
11771                        strings = new ArrayList<String>();
11772                    }
11773                    strings.add(name);
11774                    all = false;
11775                }
11776            }
11777        }
11778
11779        int build(String[] args, int opti) {
11780            for (; opti<args.length; opti++) {
11781                String name = args[opti];
11782                if ("--".equals(name)) {
11783                    return opti+1;
11784                }
11785                build(name);
11786            }
11787            return opti;
11788        }
11789
11790        boolean match(Object object, ComponentName comp) {
11791            if (all) {
11792                return true;
11793            }
11794            if (components != null) {
11795                for (int i=0; i<components.size(); i++) {
11796                    if (components.get(i).equals(comp)) {
11797                        return true;
11798                    }
11799                }
11800            }
11801            if (objects != null) {
11802                for (int i=0; i<objects.size(); i++) {
11803                    if (System.identityHashCode(object) == objects.get(i)) {
11804                        return true;
11805                    }
11806                }
11807            }
11808            if (strings != null) {
11809                String flat = comp.flattenToString();
11810                for (int i=0; i<strings.size(); i++) {
11811                    if (flat.contains(strings.get(i))) {
11812                        return true;
11813                    }
11814                }
11815            }
11816            return false;
11817        }
11818    }
11819
11820    /**
11821     * There are three things that cmd can be:
11822     *  - a flattened component name that matches an existing activity
11823     *  - the cmd arg isn't the flattened component name of an existing activity:
11824     *    dump all activity whose component contains the cmd as a substring
11825     *  - A hex number of the ActivityRecord object instance.
11826     */
11827    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
11828            int opti, boolean dumpAll) {
11829        ArrayList<ActivityRecord> activities;
11830
11831        synchronized (this) {
11832            activities = mStackSupervisor.getDumpActivitiesLocked(name);
11833        }
11834
11835        if (activities.size() <= 0) {
11836            return false;
11837        }
11838
11839        String[] newArgs = new String[args.length - opti];
11840        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11841
11842        TaskRecord lastTask = null;
11843        boolean needSep = false;
11844        for (int i=activities.size()-1; i>=0; i--) {
11845            ActivityRecord r = activities.get(i);
11846            if (needSep) {
11847                pw.println();
11848            }
11849            needSep = true;
11850            synchronized (this) {
11851                if (lastTask != r.task) {
11852                    lastTask = r.task;
11853                    pw.print("TASK "); pw.print(lastTask.affinity);
11854                            pw.print(" id="); pw.println(lastTask.taskId);
11855                    if (dumpAll) {
11856                        lastTask.dump(pw, "  ");
11857                    }
11858                }
11859            }
11860            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
11861        }
11862        return true;
11863    }
11864
11865    /**
11866     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
11867     * there is a thread associated with the activity.
11868     */
11869    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
11870            final ActivityRecord r, String[] args, boolean dumpAll) {
11871        String innerPrefix = prefix + "  ";
11872        synchronized (this) {
11873            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
11874                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
11875                    pw.print(" pid=");
11876                    if (r.app != null) pw.println(r.app.pid);
11877                    else pw.println("(not running)");
11878            if (dumpAll) {
11879                r.dump(pw, innerPrefix);
11880            }
11881        }
11882        if (r.app != null && r.app.thread != null) {
11883            // flush anything that is already in the PrintWriter since the thread is going
11884            // to write to the file descriptor directly
11885            pw.flush();
11886            try {
11887                TransferPipe tp = new TransferPipe();
11888                try {
11889                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
11890                            r.appToken, innerPrefix, args);
11891                    tp.go(fd);
11892                } finally {
11893                    tp.kill();
11894                }
11895            } catch (IOException e) {
11896                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
11897            } catch (RemoteException e) {
11898                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
11899            }
11900        }
11901    }
11902
11903    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11904            int opti, boolean dumpAll, String dumpPackage) {
11905        boolean needSep = false;
11906        boolean onlyHistory = false;
11907        boolean printedAnything = false;
11908
11909        if ("history".equals(dumpPackage)) {
11910            if (opti < args.length && "-s".equals(args[opti])) {
11911                dumpAll = false;
11912            }
11913            onlyHistory = true;
11914            dumpPackage = null;
11915        }
11916
11917        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
11918        if (!onlyHistory && dumpAll) {
11919            if (mRegisteredReceivers.size() > 0) {
11920                boolean printed = false;
11921                Iterator it = mRegisteredReceivers.values().iterator();
11922                while (it.hasNext()) {
11923                    ReceiverList r = (ReceiverList)it.next();
11924                    if (dumpPackage != null && (r.app == null ||
11925                            !dumpPackage.equals(r.app.info.packageName))) {
11926                        continue;
11927                    }
11928                    if (!printed) {
11929                        pw.println("  Registered Receivers:");
11930                        needSep = true;
11931                        printed = true;
11932                        printedAnything = true;
11933                    }
11934                    pw.print("  * "); pw.println(r);
11935                    r.dump(pw, "    ");
11936                }
11937            }
11938
11939            if (mReceiverResolver.dump(pw, needSep ?
11940                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
11941                    "    ", dumpPackage, false)) {
11942                needSep = true;
11943                printedAnything = true;
11944            }
11945        }
11946
11947        for (BroadcastQueue q : mBroadcastQueues) {
11948            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
11949            printedAnything |= needSep;
11950        }
11951
11952        needSep = true;
11953
11954        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
11955            for (int user=0; user<mStickyBroadcasts.size(); user++) {
11956                if (needSep) {
11957                    pw.println();
11958                }
11959                needSep = true;
11960                printedAnything = true;
11961                pw.print("  Sticky broadcasts for user ");
11962                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
11963                StringBuilder sb = new StringBuilder(128);
11964                for (Map.Entry<String, ArrayList<Intent>> ent
11965                        : mStickyBroadcasts.valueAt(user).entrySet()) {
11966                    pw.print("  * Sticky action "); pw.print(ent.getKey());
11967                    if (dumpAll) {
11968                        pw.println(":");
11969                        ArrayList<Intent> intents = ent.getValue();
11970                        final int N = intents.size();
11971                        for (int i=0; i<N; i++) {
11972                            sb.setLength(0);
11973                            sb.append("    Intent: ");
11974                            intents.get(i).toShortString(sb, false, true, false, false);
11975                            pw.println(sb.toString());
11976                            Bundle bundle = intents.get(i).getExtras();
11977                            if (bundle != null) {
11978                                pw.print("      ");
11979                                pw.println(bundle.toString());
11980                            }
11981                        }
11982                    } else {
11983                        pw.println("");
11984                    }
11985                }
11986            }
11987        }
11988
11989        if (!onlyHistory && dumpAll) {
11990            pw.println();
11991            for (BroadcastQueue queue : mBroadcastQueues) {
11992                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
11993                        + queue.mBroadcastsScheduled);
11994            }
11995            pw.println("  mHandler:");
11996            mHandler.dump(new PrintWriterPrinter(pw), "    ");
11997            needSep = true;
11998            printedAnything = true;
11999        }
12000
12001        if (!printedAnything) {
12002            pw.println("  (nothing)");
12003        }
12004    }
12005
12006    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12007            int opti, boolean dumpAll, String dumpPackage) {
12008        boolean needSep;
12009        boolean printedAnything = false;
12010
12011        ItemMatcher matcher = new ItemMatcher();
12012        matcher.build(args, opti);
12013
12014        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12015
12016        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12017        printedAnything |= needSep;
12018
12019        if (mLaunchingProviders.size() > 0) {
12020            boolean printed = false;
12021            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12022                ContentProviderRecord r = mLaunchingProviders.get(i);
12023                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12024                    continue;
12025                }
12026                if (!printed) {
12027                    if (needSep) pw.println();
12028                    needSep = true;
12029                    pw.println("  Launching content providers:");
12030                    printed = true;
12031                    printedAnything = true;
12032                }
12033                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12034                        pw.println(r);
12035            }
12036        }
12037
12038        if (mGrantedUriPermissions.size() > 0) {
12039            boolean printed = false;
12040            int dumpUid = -2;
12041            if (dumpPackage != null) {
12042                try {
12043                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12044                } catch (NameNotFoundException e) {
12045                    dumpUid = -1;
12046                }
12047            }
12048            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12049                int uid = mGrantedUriPermissions.keyAt(i);
12050                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12051                    continue;
12052                }
12053                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12054                if (!printed) {
12055                    if (needSep) pw.println();
12056                    needSep = true;
12057                    pw.println("  Granted Uri Permissions:");
12058                    printed = true;
12059                    printedAnything = true;
12060                }
12061                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12062                for (UriPermission perm : perms.values()) {
12063                    pw.print("    "); pw.println(perm);
12064                    if (dumpAll) {
12065                        perm.dump(pw, "      ");
12066                    }
12067                }
12068            }
12069        }
12070
12071        if (!printedAnything) {
12072            pw.println("  (nothing)");
12073        }
12074    }
12075
12076    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12077            int opti, boolean dumpAll, String dumpPackage) {
12078        boolean printed = false;
12079
12080        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12081
12082        if (mIntentSenderRecords.size() > 0) {
12083            Iterator<WeakReference<PendingIntentRecord>> it
12084                    = mIntentSenderRecords.values().iterator();
12085            while (it.hasNext()) {
12086                WeakReference<PendingIntentRecord> ref = it.next();
12087                PendingIntentRecord rec = ref != null ? ref.get(): null;
12088                if (dumpPackage != null && (rec == null
12089                        || !dumpPackage.equals(rec.key.packageName))) {
12090                    continue;
12091                }
12092                printed = true;
12093                if (rec != null) {
12094                    pw.print("  * "); pw.println(rec);
12095                    if (dumpAll) {
12096                        rec.dump(pw, "    ");
12097                    }
12098                } else {
12099                    pw.print("  * "); pw.println(ref);
12100                }
12101            }
12102        }
12103
12104        if (!printed) {
12105            pw.println("  (nothing)");
12106        }
12107    }
12108
12109    private static final int dumpProcessList(PrintWriter pw,
12110            ActivityManagerService service, List list,
12111            String prefix, String normalLabel, String persistentLabel,
12112            String dumpPackage) {
12113        int numPers = 0;
12114        final int N = list.size()-1;
12115        for (int i=N; i>=0; i--) {
12116            ProcessRecord r = (ProcessRecord)list.get(i);
12117            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12118                continue;
12119            }
12120            pw.println(String.format("%s%s #%2d: %s",
12121                    prefix, (r.persistent ? persistentLabel : normalLabel),
12122                    i, r.toString()));
12123            if (r.persistent) {
12124                numPers++;
12125            }
12126        }
12127        return numPers;
12128    }
12129
12130    private static final boolean dumpProcessOomList(PrintWriter pw,
12131            ActivityManagerService service, List<ProcessRecord> origList,
12132            String prefix, String normalLabel, String persistentLabel,
12133            boolean inclDetails, String dumpPackage) {
12134
12135        ArrayList<Pair<ProcessRecord, Integer>> list
12136                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12137        for (int i=0; i<origList.size(); i++) {
12138            ProcessRecord r = origList.get(i);
12139            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12140                continue;
12141            }
12142            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12143        }
12144
12145        if (list.size() <= 0) {
12146            return false;
12147        }
12148
12149        Comparator<Pair<ProcessRecord, Integer>> comparator
12150                = new Comparator<Pair<ProcessRecord, Integer>>() {
12151            @Override
12152            public int compare(Pair<ProcessRecord, Integer> object1,
12153                    Pair<ProcessRecord, Integer> object2) {
12154                if (object1.first.setAdj != object2.first.setAdj) {
12155                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12156                }
12157                if (object1.second.intValue() != object2.second.intValue()) {
12158                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12159                }
12160                return 0;
12161            }
12162        };
12163
12164        Collections.sort(list, comparator);
12165
12166        final long curRealtime = SystemClock.elapsedRealtime();
12167        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12168        final long curUptime = SystemClock.uptimeMillis();
12169        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12170
12171        for (int i=list.size()-1; i>=0; i--) {
12172            ProcessRecord r = list.get(i).first;
12173            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12174            char schedGroup;
12175            switch (r.setSchedGroup) {
12176                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12177                    schedGroup = 'B';
12178                    break;
12179                case Process.THREAD_GROUP_DEFAULT:
12180                    schedGroup = 'F';
12181                    break;
12182                default:
12183                    schedGroup = '?';
12184                    break;
12185            }
12186            char foreground;
12187            if (r.foregroundActivities) {
12188                foreground = 'A';
12189            } else if (r.foregroundServices) {
12190                foreground = 'S';
12191            } else {
12192                foreground = ' ';
12193            }
12194            String procState = ProcessList.makeProcStateString(r.curProcState);
12195            pw.print(prefix);
12196            pw.print(r.persistent ? persistentLabel : normalLabel);
12197            pw.print(" #");
12198            int num = (origList.size()-1)-list.get(i).second;
12199            if (num < 10) pw.print(' ');
12200            pw.print(num);
12201            pw.print(": ");
12202            pw.print(oomAdj);
12203            pw.print(' ');
12204            pw.print(schedGroup);
12205            pw.print('/');
12206            pw.print(foreground);
12207            pw.print('/');
12208            pw.print(procState);
12209            pw.print(" trm:");
12210            if (r.trimMemoryLevel < 10) pw.print(' ');
12211            pw.print(r.trimMemoryLevel);
12212            pw.print(' ');
12213            pw.print(r.toShortString());
12214            pw.print(" (");
12215            pw.print(r.adjType);
12216            pw.println(')');
12217            if (r.adjSource != null || r.adjTarget != null) {
12218                pw.print(prefix);
12219                pw.print("    ");
12220                if (r.adjTarget instanceof ComponentName) {
12221                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12222                } else if (r.adjTarget != null) {
12223                    pw.print(r.adjTarget.toString());
12224                } else {
12225                    pw.print("{null}");
12226                }
12227                pw.print("<=");
12228                if (r.adjSource instanceof ProcessRecord) {
12229                    pw.print("Proc{");
12230                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12231                    pw.println("}");
12232                } else if (r.adjSource != null) {
12233                    pw.println(r.adjSource.toString());
12234                } else {
12235                    pw.println("{null}");
12236                }
12237            }
12238            if (inclDetails) {
12239                pw.print(prefix);
12240                pw.print("    ");
12241                pw.print("oom: max="); pw.print(r.maxAdj);
12242                pw.print(" curRaw="); pw.print(r.curRawAdj);
12243                pw.print(" setRaw="); pw.print(r.setRawAdj);
12244                pw.print(" cur="); pw.print(r.curAdj);
12245                pw.print(" set="); pw.println(r.setAdj);
12246                pw.print(prefix);
12247                pw.print("    ");
12248                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12249                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12250                pw.print(" lastPss="); pw.print(r.lastPss);
12251                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12252                pw.print(prefix);
12253                pw.print("    ");
12254                pw.print("keeping="); pw.print(r.keeping);
12255                pw.print(" cached="); pw.print(r.cached);
12256                pw.print(" empty="); pw.print(r.empty);
12257                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12258
12259                if (!r.keeping) {
12260                    if (r.lastWakeTime != 0) {
12261                        long wtime;
12262                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12263                        synchronized (stats) {
12264                            wtime = stats.getProcessWakeTime(r.info.uid,
12265                                    r.pid, curRealtime);
12266                        }
12267                        long timeUsed = wtime - r.lastWakeTime;
12268                        pw.print(prefix);
12269                        pw.print("    ");
12270                        pw.print("keep awake over ");
12271                        TimeUtils.formatDuration(realtimeSince, pw);
12272                        pw.print(" used ");
12273                        TimeUtils.formatDuration(timeUsed, pw);
12274                        pw.print(" (");
12275                        pw.print((timeUsed*100)/realtimeSince);
12276                        pw.println("%)");
12277                    }
12278                    if (r.lastCpuTime != 0) {
12279                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12280                        pw.print(prefix);
12281                        pw.print("    ");
12282                        pw.print("run cpu over ");
12283                        TimeUtils.formatDuration(uptimeSince, pw);
12284                        pw.print(" used ");
12285                        TimeUtils.formatDuration(timeUsed, pw);
12286                        pw.print(" (");
12287                        pw.print((timeUsed*100)/uptimeSince);
12288                        pw.println("%)");
12289                    }
12290                }
12291            }
12292        }
12293        return true;
12294    }
12295
12296    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12297        ArrayList<ProcessRecord> procs;
12298        synchronized (this) {
12299            if (args != null && args.length > start
12300                    && args[start].charAt(0) != '-') {
12301                procs = new ArrayList<ProcessRecord>();
12302                int pid = -1;
12303                try {
12304                    pid = Integer.parseInt(args[start]);
12305                } catch (NumberFormatException e) {
12306                }
12307                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12308                    ProcessRecord proc = mLruProcesses.get(i);
12309                    if (proc.pid == pid) {
12310                        procs.add(proc);
12311                    } else if (proc.processName.equals(args[start])) {
12312                        procs.add(proc);
12313                    }
12314                }
12315                if (procs.size() <= 0) {
12316                    return null;
12317                }
12318            } else {
12319                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12320            }
12321        }
12322        return procs;
12323    }
12324
12325    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12326            PrintWriter pw, String[] args) {
12327        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12328        if (procs == null) {
12329            pw.println("No process found for: " + args[0]);
12330            return;
12331        }
12332
12333        long uptime = SystemClock.uptimeMillis();
12334        long realtime = SystemClock.elapsedRealtime();
12335        pw.println("Applications Graphics Acceleration Info:");
12336        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12337
12338        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12339            ProcessRecord r = procs.get(i);
12340            if (r.thread != null) {
12341                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12342                pw.flush();
12343                try {
12344                    TransferPipe tp = new TransferPipe();
12345                    try {
12346                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12347                        tp.go(fd);
12348                    } finally {
12349                        tp.kill();
12350                    }
12351                } catch (IOException e) {
12352                    pw.println("Failure while dumping the app: " + r);
12353                    pw.flush();
12354                } catch (RemoteException e) {
12355                    pw.println("Got a RemoteException while dumping the app " + r);
12356                    pw.flush();
12357                }
12358            }
12359        }
12360    }
12361
12362    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12363        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12364        if (procs == null) {
12365            pw.println("No process found for: " + args[0]);
12366            return;
12367        }
12368
12369        pw.println("Applications Database Info:");
12370
12371        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12372            ProcessRecord r = procs.get(i);
12373            if (r.thread != null) {
12374                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12375                pw.flush();
12376                try {
12377                    TransferPipe tp = new TransferPipe();
12378                    try {
12379                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12380                        tp.go(fd);
12381                    } finally {
12382                        tp.kill();
12383                    }
12384                } catch (IOException e) {
12385                    pw.println("Failure while dumping the app: " + r);
12386                    pw.flush();
12387                } catch (RemoteException e) {
12388                    pw.println("Got a RemoteException while dumping the app " + r);
12389                    pw.flush();
12390                }
12391            }
12392        }
12393    }
12394
12395    final static class MemItem {
12396        final boolean isProc;
12397        final String label;
12398        final String shortLabel;
12399        final long pss;
12400        final int id;
12401        final boolean hasActivities;
12402        ArrayList<MemItem> subitems;
12403
12404        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12405                boolean _hasActivities) {
12406            isProc = true;
12407            label = _label;
12408            shortLabel = _shortLabel;
12409            pss = _pss;
12410            id = _id;
12411            hasActivities = _hasActivities;
12412        }
12413
12414        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12415            isProc = false;
12416            label = _label;
12417            shortLabel = _shortLabel;
12418            pss = _pss;
12419            id = _id;
12420            hasActivities = false;
12421        }
12422    }
12423
12424    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12425            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12426        if (sort && !isCompact) {
12427            Collections.sort(items, new Comparator<MemItem>() {
12428                @Override
12429                public int compare(MemItem lhs, MemItem rhs) {
12430                    if (lhs.pss < rhs.pss) {
12431                        return 1;
12432                    } else if (lhs.pss > rhs.pss) {
12433                        return -1;
12434                    }
12435                    return 0;
12436                }
12437            });
12438        }
12439
12440        for (int i=0; i<items.size(); i++) {
12441            MemItem mi = items.get(i);
12442            if (!isCompact) {
12443                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12444            } else if (mi.isProc) {
12445                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12446                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12447                pw.println(mi.hasActivities ? ",a" : ",e");
12448            } else {
12449                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12450                pw.println(mi.pss);
12451            }
12452            if (mi.subitems != null) {
12453                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12454                        true, isCompact);
12455            }
12456        }
12457    }
12458
12459    // These are in KB.
12460    static final long[] DUMP_MEM_BUCKETS = new long[] {
12461        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12462        120*1024, 160*1024, 200*1024,
12463        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12464        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12465    };
12466
12467    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12468            boolean stackLike) {
12469        int start = label.lastIndexOf('.');
12470        if (start >= 0) start++;
12471        else start = 0;
12472        int end = label.length();
12473        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12474            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12475                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12476                out.append(bucket);
12477                out.append(stackLike ? "MB." : "MB ");
12478                out.append(label, start, end);
12479                return;
12480            }
12481        }
12482        out.append(memKB/1024);
12483        out.append(stackLike ? "MB." : "MB ");
12484        out.append(label, start, end);
12485    }
12486
12487    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12488            ProcessList.NATIVE_ADJ,
12489            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12490            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12491            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12492            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12493            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12494    };
12495    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12496            "Native",
12497            "System", "Persistent", "Foreground",
12498            "Visible", "Perceptible",
12499            "Heavy Weight", "Backup",
12500            "A Services", "Home",
12501            "Previous", "B Services", "Cached"
12502    };
12503    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12504            "native",
12505            "sys", "pers", "fore",
12506            "vis", "percept",
12507            "heavy", "backup",
12508            "servicea", "home",
12509            "prev", "serviceb", "cached"
12510    };
12511
12512    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12513            long realtime, boolean isCheckinRequest, boolean isCompact) {
12514        if (isCheckinRequest || isCompact) {
12515            // short checkin version
12516            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12517        } else {
12518            pw.println("Applications Memory Usage (kB):");
12519            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12520        }
12521    }
12522
12523    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12524            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12525        boolean dumpDetails = false;
12526        boolean dumpFullDetails = false;
12527        boolean dumpDalvik = false;
12528        boolean oomOnly = false;
12529        boolean isCompact = false;
12530        boolean localOnly = false;
12531
12532        int opti = 0;
12533        while (opti < args.length) {
12534            String opt = args[opti];
12535            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12536                break;
12537            }
12538            opti++;
12539            if ("-a".equals(opt)) {
12540                dumpDetails = true;
12541                dumpFullDetails = true;
12542                dumpDalvik = true;
12543            } else if ("-d".equals(opt)) {
12544                dumpDalvik = true;
12545            } else if ("-c".equals(opt)) {
12546                isCompact = true;
12547            } else if ("--oom".equals(opt)) {
12548                oomOnly = true;
12549            } else if ("--local".equals(opt)) {
12550                localOnly = true;
12551            } else if ("-h".equals(opt)) {
12552                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12553                pw.println("  -a: include all available information for each process.");
12554                pw.println("  -d: include dalvik details when dumping process details.");
12555                pw.println("  -c: dump in a compact machine-parseable representation.");
12556                pw.println("  --oom: only show processes organized by oom adj.");
12557                pw.println("  --local: only collect details locally, don't call process.");
12558                pw.println("If [process] is specified it can be the name or ");
12559                pw.println("pid of a specific process to dump.");
12560                return;
12561            } else {
12562                pw.println("Unknown argument: " + opt + "; use -h for help");
12563            }
12564        }
12565
12566        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12567        long uptime = SystemClock.uptimeMillis();
12568        long realtime = SystemClock.elapsedRealtime();
12569        final long[] tmpLong = new long[1];
12570
12571        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12572        if (procs == null) {
12573            // No Java processes.  Maybe they want to print a native process.
12574            if (args != null && args.length > opti
12575                    && args[opti].charAt(0) != '-') {
12576                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12577                        = new ArrayList<ProcessCpuTracker.Stats>();
12578                updateCpuStatsNow();
12579                int findPid = -1;
12580                try {
12581                    findPid = Integer.parseInt(args[opti]);
12582                } catch (NumberFormatException e) {
12583                }
12584                synchronized (mProcessCpuThread) {
12585                    final int N = mProcessCpuTracker.countStats();
12586                    for (int i=0; i<N; i++) {
12587                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12588                        if (st.pid == findPid || (st.baseName != null
12589                                && st.baseName.equals(args[opti]))) {
12590                            nativeProcs.add(st);
12591                        }
12592                    }
12593                }
12594                if (nativeProcs.size() > 0) {
12595                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12596                            isCompact);
12597                    Debug.MemoryInfo mi = null;
12598                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12599                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12600                        final int pid = r.pid;
12601                        if (!isCheckinRequest && dumpDetails) {
12602                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12603                        }
12604                        if (mi == null) {
12605                            mi = new Debug.MemoryInfo();
12606                        }
12607                        if (dumpDetails || (!brief && !oomOnly)) {
12608                            Debug.getMemoryInfo(pid, mi);
12609                        } else {
12610                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12611                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12612                        }
12613                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12614                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12615                        if (isCheckinRequest) {
12616                            pw.println();
12617                        }
12618                    }
12619                    return;
12620                }
12621            }
12622            pw.println("No process found for: " + args[opti]);
12623            return;
12624        }
12625
12626        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12627            dumpDetails = true;
12628        }
12629
12630        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12631
12632        String[] innerArgs = new String[args.length-opti];
12633        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12634
12635        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12636        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12637        long nativePss=0, dalvikPss=0, otherPss=0;
12638        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12639
12640        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12641        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12642                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12643
12644        long totalPss = 0;
12645        long cachedPss = 0;
12646
12647        Debug.MemoryInfo mi = null;
12648        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12649            final ProcessRecord r = procs.get(i);
12650            final IApplicationThread thread;
12651            final int pid;
12652            final int oomAdj;
12653            final boolean hasActivities;
12654            synchronized (this) {
12655                thread = r.thread;
12656                pid = r.pid;
12657                oomAdj = r.getSetAdjWithServices();
12658                hasActivities = r.activities.size() > 0;
12659            }
12660            if (thread != null) {
12661                if (!isCheckinRequest && dumpDetails) {
12662                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
12663                }
12664                if (mi == null) {
12665                    mi = new Debug.MemoryInfo();
12666                }
12667                if (dumpDetails || (!brief && !oomOnly)) {
12668                    Debug.getMemoryInfo(pid, mi);
12669                } else {
12670                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12671                    mi.dalvikPrivateDirty = (int)tmpLong[0];
12672                }
12673                if (dumpDetails) {
12674                    if (localOnly) {
12675                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12676                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
12677                        if (isCheckinRequest) {
12678                            pw.println();
12679                        }
12680                    } else {
12681                        try {
12682                            pw.flush();
12683                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
12684                                    dumpDalvik, innerArgs);
12685                        } catch (RemoteException e) {
12686                            if (!isCheckinRequest) {
12687                                pw.println("Got RemoteException!");
12688                                pw.flush();
12689                            }
12690                        }
12691                    }
12692                }
12693
12694                final long myTotalPss = mi.getTotalPss();
12695                final long myTotalUss = mi.getTotalUss();
12696
12697                synchronized (this) {
12698                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
12699                        // Record this for posterity if the process has been stable.
12700                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
12701                    }
12702                }
12703
12704                if (!isCheckinRequest && mi != null) {
12705                    totalPss += myTotalPss;
12706                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
12707                            (hasActivities ? " / activities)" : ")"),
12708                            r.processName, myTotalPss, pid, hasActivities);
12709                    procMems.add(pssItem);
12710                    procMemsMap.put(pid, pssItem);
12711
12712                    nativePss += mi.nativePss;
12713                    dalvikPss += mi.dalvikPss;
12714                    otherPss += mi.otherPss;
12715                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12716                        long mem = mi.getOtherPss(j);
12717                        miscPss[j] += mem;
12718                        otherPss -= mem;
12719                    }
12720
12721                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
12722                        cachedPss += myTotalPss;
12723                    }
12724
12725                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
12726                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
12727                                || oomIndex == (oomPss.length-1)) {
12728                            oomPss[oomIndex] += myTotalPss;
12729                            if (oomProcs[oomIndex] == null) {
12730                                oomProcs[oomIndex] = new ArrayList<MemItem>();
12731                            }
12732                            oomProcs[oomIndex].add(pssItem);
12733                            break;
12734                        }
12735                    }
12736                }
12737            }
12738        }
12739
12740        long nativeProcTotalPss = 0;
12741
12742        if (!isCheckinRequest && procs.size() > 1) {
12743            // If we are showing aggregations, also look for native processes to
12744            // include so that our aggregations are more accurate.
12745            updateCpuStatsNow();
12746            synchronized (mProcessCpuThread) {
12747                final int N = mProcessCpuTracker.countStats();
12748                for (int i=0; i<N; i++) {
12749                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12750                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
12751                        if (mi == null) {
12752                            mi = new Debug.MemoryInfo();
12753                        }
12754                        if (!brief && !oomOnly) {
12755                            Debug.getMemoryInfo(st.pid, mi);
12756                        } else {
12757                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
12758                            mi.nativePrivateDirty = (int)tmpLong[0];
12759                        }
12760
12761                        final long myTotalPss = mi.getTotalPss();
12762                        totalPss += myTotalPss;
12763                        nativeProcTotalPss += myTotalPss;
12764
12765                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
12766                                st.name, myTotalPss, st.pid, false);
12767                        procMems.add(pssItem);
12768
12769                        nativePss += mi.nativePss;
12770                        dalvikPss += mi.dalvikPss;
12771                        otherPss += mi.otherPss;
12772                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12773                            long mem = mi.getOtherPss(j);
12774                            miscPss[j] += mem;
12775                            otherPss -= mem;
12776                        }
12777                        oomPss[0] += myTotalPss;
12778                        if (oomProcs[0] == null) {
12779                            oomProcs[0] = new ArrayList<MemItem>();
12780                        }
12781                        oomProcs[0].add(pssItem);
12782                    }
12783                }
12784            }
12785
12786            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
12787
12788            catMems.add(new MemItem("Native", "Native", nativePss, -1));
12789            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
12790            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
12791            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
12792                String label = Debug.MemoryInfo.getOtherLabel(j);
12793                catMems.add(new MemItem(label, label, miscPss[j], j));
12794            }
12795
12796            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
12797            for (int j=0; j<oomPss.length; j++) {
12798                if (oomPss[j] != 0) {
12799                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
12800                            : DUMP_MEM_OOM_LABEL[j];
12801                    MemItem item = new MemItem(label, label, oomPss[j],
12802                            DUMP_MEM_OOM_ADJ[j]);
12803                    item.subitems = oomProcs[j];
12804                    oomMems.add(item);
12805                }
12806            }
12807
12808            if (!brief && !oomOnly && !isCompact) {
12809                pw.println();
12810                pw.println("Total PSS by process:");
12811                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
12812                pw.println();
12813            }
12814            if (!isCompact) {
12815                pw.println("Total PSS by OOM adjustment:");
12816            }
12817            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
12818            if (!brief && !oomOnly) {
12819                PrintWriter out = categoryPw != null ? categoryPw : pw;
12820                if (!isCompact) {
12821                    out.println();
12822                    out.println("Total PSS by category:");
12823                }
12824                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
12825            }
12826            if (!isCompact) {
12827                pw.println();
12828            }
12829            MemInfoReader memInfo = new MemInfoReader();
12830            memInfo.readMemInfo();
12831            if (nativeProcTotalPss > 0) {
12832                synchronized (this) {
12833                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
12834                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
12835                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
12836                            nativeProcTotalPss);
12837                }
12838            }
12839            if (!brief) {
12840                if (!isCompact) {
12841                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
12842                    pw.print(" kB (status ");
12843                    switch (mLastMemoryLevel) {
12844                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
12845                            pw.println("normal)");
12846                            break;
12847                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
12848                            pw.println("moderate)");
12849                            break;
12850                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
12851                            pw.println("low)");
12852                            break;
12853                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
12854                            pw.println("critical)");
12855                            break;
12856                        default:
12857                            pw.print(mLastMemoryLevel);
12858                            pw.println(")");
12859                            break;
12860                    }
12861                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
12862                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
12863                            pw.print(cachedPss); pw.print(" cached pss + ");
12864                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
12865                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
12866                } else {
12867                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
12868                    pw.print(cachedPss + memInfo.getCachedSizeKb()
12869                            + memInfo.getFreeSizeKb()); pw.print(",");
12870                    pw.println(totalPss - cachedPss);
12871                }
12872            }
12873            if (!isCompact) {
12874                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
12875                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
12876                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
12877                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
12878                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
12879                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
12880                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
12881                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
12882                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
12883                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
12884                        - memInfo.getSlabSizeKb()); pw.println(" kB");
12885            }
12886            if (!brief) {
12887                if (memInfo.getZramTotalSizeKb() != 0) {
12888                    if (!isCompact) {
12889                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
12890                                pw.print(" kB physical used for ");
12891                                pw.print(memInfo.getSwapTotalSizeKb()
12892                                        - memInfo.getSwapFreeSizeKb());
12893                                pw.print(" kB in swap (");
12894                                pw.print(memInfo.getSwapTotalSizeKb());
12895                                pw.println(" kB total swap)");
12896                    } else {
12897                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
12898                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
12899                                pw.println(memInfo.getSwapFreeSizeKb());
12900                    }
12901                }
12902                final int[] SINGLE_LONG_FORMAT = new int[] {
12903                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
12904                };
12905                long[] longOut = new long[1];
12906                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
12907                        SINGLE_LONG_FORMAT, null, longOut, null);
12908                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12909                longOut[0] = 0;
12910                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
12911                        SINGLE_LONG_FORMAT, null, longOut, null);
12912                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12913                longOut[0] = 0;
12914                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
12915                        SINGLE_LONG_FORMAT, null, longOut, null);
12916                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12917                longOut[0] = 0;
12918                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
12919                        SINGLE_LONG_FORMAT, null, longOut, null);
12920                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
12921                if (!isCompact) {
12922                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
12923                        pw.print("      KSM: "); pw.print(sharing);
12924                                pw.print(" kB saved from shared ");
12925                                pw.print(shared); pw.println(" kB");
12926                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
12927                                pw.print(voltile); pw.println(" kB volatile");
12928                    }
12929                    pw.print("   Tuning: ");
12930                    pw.print(ActivityManager.staticGetMemoryClass());
12931                    pw.print(" (large ");
12932                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12933                    pw.print("), oom ");
12934                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12935                    pw.print(" kB");
12936                    pw.print(", restore limit ");
12937                    pw.print(mProcessList.getCachedRestoreThresholdKb());
12938                    pw.print(" kB");
12939                    if (ActivityManager.isLowRamDeviceStatic()) {
12940                        pw.print(" (low-ram)");
12941                    }
12942                    if (ActivityManager.isHighEndGfx()) {
12943                        pw.print(" (high-end-gfx)");
12944                    }
12945                    pw.println();
12946                } else {
12947                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
12948                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
12949                    pw.println(voltile);
12950                    pw.print("tuning,");
12951                    pw.print(ActivityManager.staticGetMemoryClass());
12952                    pw.print(',');
12953                    pw.print(ActivityManager.staticGetLargeMemoryClass());
12954                    pw.print(',');
12955                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
12956                    if (ActivityManager.isLowRamDeviceStatic()) {
12957                        pw.print(",low-ram");
12958                    }
12959                    if (ActivityManager.isHighEndGfx()) {
12960                        pw.print(",high-end-gfx");
12961                    }
12962                    pw.println();
12963                }
12964            }
12965        }
12966    }
12967
12968    /**
12969     * Searches array of arguments for the specified string
12970     * @param args array of argument strings
12971     * @param value value to search for
12972     * @return true if the value is contained in the array
12973     */
12974    private static boolean scanArgs(String[] args, String value) {
12975        if (args != null) {
12976            for (String arg : args) {
12977                if (value.equals(arg)) {
12978                    return true;
12979                }
12980            }
12981        }
12982        return false;
12983    }
12984
12985    private final boolean removeDyingProviderLocked(ProcessRecord proc,
12986            ContentProviderRecord cpr, boolean always) {
12987        final boolean inLaunching = mLaunchingProviders.contains(cpr);
12988
12989        if (!inLaunching || always) {
12990            synchronized (cpr) {
12991                cpr.launchingApp = null;
12992                cpr.notifyAll();
12993            }
12994            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
12995            String names[] = cpr.info.authority.split(";");
12996            for (int j = 0; j < names.length; j++) {
12997                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
12998            }
12999        }
13000
13001        for (int i=0; i<cpr.connections.size(); i++) {
13002            ContentProviderConnection conn = cpr.connections.get(i);
13003            if (conn.waiting) {
13004                // If this connection is waiting for the provider, then we don't
13005                // need to mess with its process unless we are always removing
13006                // or for some reason the provider is not currently launching.
13007                if (inLaunching && !always) {
13008                    continue;
13009                }
13010            }
13011            ProcessRecord capp = conn.client;
13012            conn.dead = true;
13013            if (conn.stableCount > 0) {
13014                if (!capp.persistent && capp.thread != null
13015                        && capp.pid != 0
13016                        && capp.pid != MY_PID) {
13017                    killUnneededProcessLocked(capp, "depends on provider "
13018                            + cpr.name.flattenToShortString()
13019                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13020                }
13021            } else if (capp.thread != null && conn.provider.provider != null) {
13022                try {
13023                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13024                } catch (RemoteException e) {
13025                }
13026                // In the protocol here, we don't expect the client to correctly
13027                // clean up this connection, we'll just remove it.
13028                cpr.connections.remove(i);
13029                conn.client.conProviders.remove(conn);
13030            }
13031        }
13032
13033        if (inLaunching && always) {
13034            mLaunchingProviders.remove(cpr);
13035        }
13036        return inLaunching;
13037    }
13038
13039    /**
13040     * Main code for cleaning up a process when it has gone away.  This is
13041     * called both as a result of the process dying, or directly when stopping
13042     * a process when running in single process mode.
13043     */
13044    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13045            boolean restarting, boolean allowRestart, int index) {
13046        if (index >= 0) {
13047            removeLruProcessLocked(app);
13048            ProcessList.remove(app.pid);
13049        }
13050
13051        mProcessesToGc.remove(app);
13052        mPendingPssProcesses.remove(app);
13053
13054        // Dismiss any open dialogs.
13055        if (app.crashDialog != null && !app.forceCrashReport) {
13056            app.crashDialog.dismiss();
13057            app.crashDialog = null;
13058        }
13059        if (app.anrDialog != null) {
13060            app.anrDialog.dismiss();
13061            app.anrDialog = null;
13062        }
13063        if (app.waitDialog != null) {
13064            app.waitDialog.dismiss();
13065            app.waitDialog = null;
13066        }
13067
13068        app.crashing = false;
13069        app.notResponding = false;
13070
13071        app.resetPackageList(mProcessStats);
13072        app.unlinkDeathRecipient();
13073        app.makeInactive(mProcessStats);
13074        app.waitingToKill = null;
13075        app.forcingToForeground = null;
13076        updateProcessForegroundLocked(app, false, false);
13077        app.foregroundActivities = false;
13078        app.hasShownUi = false;
13079        app.treatLikeActivity = false;
13080        app.hasAboveClient = false;
13081        app.hasClientActivities = false;
13082
13083        mServices.killServicesLocked(app, allowRestart);
13084
13085        boolean restart = false;
13086
13087        // Remove published content providers.
13088        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13089            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13090            final boolean always = app.bad || !allowRestart;
13091            if (removeDyingProviderLocked(app, cpr, always) || always) {
13092                // We left the provider in the launching list, need to
13093                // restart it.
13094                restart = true;
13095            }
13096
13097            cpr.provider = null;
13098            cpr.proc = null;
13099        }
13100        app.pubProviders.clear();
13101
13102        // Take care of any launching providers waiting for this process.
13103        if (checkAppInLaunchingProvidersLocked(app, false)) {
13104            restart = true;
13105        }
13106
13107        // Unregister from connected content providers.
13108        if (!app.conProviders.isEmpty()) {
13109            for (int i=0; i<app.conProviders.size(); i++) {
13110                ContentProviderConnection conn = app.conProviders.get(i);
13111                conn.provider.connections.remove(conn);
13112            }
13113            app.conProviders.clear();
13114        }
13115
13116        // At this point there may be remaining entries in mLaunchingProviders
13117        // where we were the only one waiting, so they are no longer of use.
13118        // Look for these and clean up if found.
13119        // XXX Commented out for now.  Trying to figure out a way to reproduce
13120        // the actual situation to identify what is actually going on.
13121        if (false) {
13122            for (int i=0; i<mLaunchingProviders.size(); i++) {
13123                ContentProviderRecord cpr = (ContentProviderRecord)
13124                        mLaunchingProviders.get(i);
13125                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13126                    synchronized (cpr) {
13127                        cpr.launchingApp = null;
13128                        cpr.notifyAll();
13129                    }
13130                }
13131            }
13132        }
13133
13134        skipCurrentReceiverLocked(app);
13135
13136        // Unregister any receivers.
13137        for (int i=app.receivers.size()-1; i>=0; i--) {
13138            removeReceiverLocked(app.receivers.valueAt(i));
13139        }
13140        app.receivers.clear();
13141
13142        // If the app is undergoing backup, tell the backup manager about it
13143        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13144            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13145                    + mBackupTarget.appInfo + " died during backup");
13146            try {
13147                IBackupManager bm = IBackupManager.Stub.asInterface(
13148                        ServiceManager.getService(Context.BACKUP_SERVICE));
13149                bm.agentDisconnected(app.info.packageName);
13150            } catch (RemoteException e) {
13151                // can't happen; backup manager is local
13152            }
13153        }
13154
13155        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13156            ProcessChangeItem item = mPendingProcessChanges.get(i);
13157            if (item.pid == app.pid) {
13158                mPendingProcessChanges.remove(i);
13159                mAvailProcessChanges.add(item);
13160            }
13161        }
13162        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13163
13164        // If the caller is restarting this app, then leave it in its
13165        // current lists and let the caller take care of it.
13166        if (restarting) {
13167            return;
13168        }
13169
13170        if (!app.persistent || app.isolated) {
13171            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13172                    "Removing non-persistent process during cleanup: " + app);
13173            mProcessNames.remove(app.processName, app.uid);
13174            mIsolatedProcesses.remove(app.uid);
13175            if (mHeavyWeightProcess == app) {
13176                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13177                        mHeavyWeightProcess.userId, 0));
13178                mHeavyWeightProcess = null;
13179            }
13180        } else if (!app.removed) {
13181            // This app is persistent, so we need to keep its record around.
13182            // If it is not already on the pending app list, add it there
13183            // and start a new process for it.
13184            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13185                mPersistentStartingProcesses.add(app);
13186                restart = true;
13187            }
13188        }
13189        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13190                "Clean-up removing on hold: " + app);
13191        mProcessesOnHold.remove(app);
13192
13193        if (app == mHomeProcess) {
13194            mHomeProcess = null;
13195        }
13196        if (app == mPreviousProcess) {
13197            mPreviousProcess = null;
13198        }
13199
13200        if (restart && !app.isolated) {
13201            // We have components that still need to be running in the
13202            // process, so re-launch it.
13203            mProcessNames.put(app.processName, app.uid, app);
13204            startProcessLocked(app, "restart", app.processName, null /* ABI override */);
13205        } else if (app.pid > 0 && app.pid != MY_PID) {
13206            // Goodbye!
13207            boolean removed;
13208            synchronized (mPidsSelfLocked) {
13209                mPidsSelfLocked.remove(app.pid);
13210                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13211            }
13212            mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_PROC_FINISH,
13213                    app.processName, app.info.uid);
13214            if (app.isolated) {
13215                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13216            }
13217            app.setPid(0);
13218        }
13219    }
13220
13221    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13222        // Look through the content providers we are waiting to have launched,
13223        // and if any run in this process then either schedule a restart of
13224        // the process or kill the client waiting for it if this process has
13225        // gone bad.
13226        int NL = mLaunchingProviders.size();
13227        boolean restart = false;
13228        for (int i=0; i<NL; i++) {
13229            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13230            if (cpr.launchingApp == app) {
13231                if (!alwaysBad && !app.bad) {
13232                    restart = true;
13233                } else {
13234                    removeDyingProviderLocked(app, cpr, true);
13235                    // cpr should have been removed from mLaunchingProviders
13236                    NL = mLaunchingProviders.size();
13237                    i--;
13238                }
13239            }
13240        }
13241        return restart;
13242    }
13243
13244    // =========================================================
13245    // SERVICES
13246    // =========================================================
13247
13248    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13249            int flags) {
13250        enforceNotIsolatedCaller("getServices");
13251        synchronized (this) {
13252            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13253        }
13254    }
13255
13256    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13257        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13258        synchronized (this) {
13259            return mServices.getRunningServiceControlPanelLocked(name);
13260        }
13261    }
13262
13263    public ComponentName startService(IApplicationThread caller, Intent service,
13264            String resolvedType, int userId) {
13265        enforceNotIsolatedCaller("startService");
13266        // Refuse possible leaked file descriptors
13267        if (service != null && service.hasFileDescriptors() == true) {
13268            throw new IllegalArgumentException("File descriptors passed in Intent");
13269        }
13270
13271        if (DEBUG_SERVICE)
13272            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13273        synchronized(this) {
13274            final int callingPid = Binder.getCallingPid();
13275            final int callingUid = Binder.getCallingUid();
13276            final long origId = Binder.clearCallingIdentity();
13277            ComponentName res = mServices.startServiceLocked(caller, service,
13278                    resolvedType, callingPid, callingUid, userId);
13279            Binder.restoreCallingIdentity(origId);
13280            return res;
13281        }
13282    }
13283
13284    ComponentName startServiceInPackage(int uid,
13285            Intent service, String resolvedType, int userId) {
13286        synchronized(this) {
13287            if (DEBUG_SERVICE)
13288                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13289            final long origId = Binder.clearCallingIdentity();
13290            ComponentName res = mServices.startServiceLocked(null, service,
13291                    resolvedType, -1, uid, userId);
13292            Binder.restoreCallingIdentity(origId);
13293            return res;
13294        }
13295    }
13296
13297    public int stopService(IApplicationThread caller, Intent service,
13298            String resolvedType, int userId) {
13299        enforceNotIsolatedCaller("stopService");
13300        // Refuse possible leaked file descriptors
13301        if (service != null && service.hasFileDescriptors() == true) {
13302            throw new IllegalArgumentException("File descriptors passed in Intent");
13303        }
13304
13305        synchronized(this) {
13306            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13307        }
13308    }
13309
13310    public IBinder peekService(Intent service, String resolvedType) {
13311        enforceNotIsolatedCaller("peekService");
13312        // Refuse possible leaked file descriptors
13313        if (service != null && service.hasFileDescriptors() == true) {
13314            throw new IllegalArgumentException("File descriptors passed in Intent");
13315        }
13316        synchronized(this) {
13317            return mServices.peekServiceLocked(service, resolvedType);
13318        }
13319    }
13320
13321    public boolean stopServiceToken(ComponentName className, IBinder token,
13322            int startId) {
13323        synchronized(this) {
13324            return mServices.stopServiceTokenLocked(className, token, startId);
13325        }
13326    }
13327
13328    public void setServiceForeground(ComponentName className, IBinder token,
13329            int id, Notification notification, boolean removeNotification) {
13330        synchronized(this) {
13331            mServices.setServiceForegroundLocked(className, token, id, notification,
13332                    removeNotification);
13333        }
13334    }
13335
13336    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13337            boolean requireFull, String name, String callerPackage) {
13338        final int callingUserId = UserHandle.getUserId(callingUid);
13339        if (callingUserId != userId) {
13340            if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13341                if ((requireFull || checkComponentPermission(
13342                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13343                        callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
13344                        && checkComponentPermission(INTERACT_ACROSS_USERS_FULL,
13345                                callingPid, callingUid, -1, true)
13346                                != PackageManager.PERMISSION_GRANTED) {
13347                    if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13348                        // In this case, they would like to just execute as their
13349                        // owner user instead of failing.
13350                        userId = callingUserId;
13351                    } else {
13352                        StringBuilder builder = new StringBuilder(128);
13353                        builder.append("Permission Denial: ");
13354                        builder.append(name);
13355                        if (callerPackage != null) {
13356                            builder.append(" from ");
13357                            builder.append(callerPackage);
13358                        }
13359                        builder.append(" asks to run as user ");
13360                        builder.append(userId);
13361                        builder.append(" but is calling from user ");
13362                        builder.append(UserHandle.getUserId(callingUid));
13363                        builder.append("; this requires ");
13364                        builder.append(INTERACT_ACROSS_USERS_FULL);
13365                        if (!requireFull) {
13366                            builder.append(" or ");
13367                            builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
13368                        }
13369                        String msg = builder.toString();
13370                        Slog.w(TAG, msg);
13371                        throw new SecurityException(msg);
13372                    }
13373                }
13374            }
13375            if (userId == UserHandle.USER_CURRENT
13376                    || userId == UserHandle.USER_CURRENT_OR_SELF) {
13377                // Note that we may be accessing this outside of a lock...
13378                // shouldn't be a big deal, if this is being called outside
13379                // of a locked context there is intrinsically a race with
13380                // the value the caller will receive and someone else changing it.
13381                userId = mCurrentUserId;
13382            }
13383            if (!allowAll && userId < 0) {
13384                throw new IllegalArgumentException(
13385                        "Call does not support special user #" + userId);
13386            }
13387        }
13388        return userId;
13389    }
13390
13391    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13392            String className, int flags) {
13393        boolean result = false;
13394        // For apps that don't have pre-defined UIDs, check for permission
13395        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13396            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13397                if (ActivityManager.checkUidPermission(
13398                        android.Manifest.permission.INTERACT_ACROSS_USERS,
13399                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13400                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13401                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13402                            + " requests FLAG_SINGLE_USER, but app does not hold "
13403                            + android.Manifest.permission.INTERACT_ACROSS_USERS;
13404                    Slog.w(TAG, msg);
13405                    throw new SecurityException(msg);
13406                }
13407                // Permission passed
13408                result = true;
13409            }
13410        } else if ("system".equals(componentProcessName)) {
13411            result = true;
13412        } else {
13413            // App with pre-defined UID, check if it's a persistent app
13414            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13415        }
13416        if (DEBUG_MU) {
13417            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13418                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13419        }
13420        return result;
13421    }
13422
13423    /**
13424     * Checks to see if the caller is in the same app as the singleton
13425     * component, or the component is in a special app. It allows special apps
13426     * to export singleton components but prevents exporting singleton
13427     * components for regular apps.
13428     */
13429    boolean isValidSingletonCall(int callingUid, int componentUid) {
13430        int componentAppId = UserHandle.getAppId(componentUid);
13431        return UserHandle.isSameApp(callingUid, componentUid)
13432                || componentAppId == Process.SYSTEM_UID
13433                || componentAppId == Process.PHONE_UID
13434                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13435                        == PackageManager.PERMISSION_GRANTED;
13436    }
13437
13438    public int bindService(IApplicationThread caller, IBinder token,
13439            Intent service, String resolvedType,
13440            IServiceConnection connection, int flags, int userId) {
13441        enforceNotIsolatedCaller("bindService");
13442        // Refuse possible leaked file descriptors
13443        if (service != null && service.hasFileDescriptors() == true) {
13444            throw new IllegalArgumentException("File descriptors passed in Intent");
13445        }
13446
13447        synchronized(this) {
13448            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13449                    connection, flags, userId);
13450        }
13451    }
13452
13453    public boolean unbindService(IServiceConnection connection) {
13454        synchronized (this) {
13455            return mServices.unbindServiceLocked(connection);
13456        }
13457    }
13458
13459    public void publishService(IBinder token, Intent intent, IBinder service) {
13460        // Refuse possible leaked file descriptors
13461        if (intent != null && intent.hasFileDescriptors() == true) {
13462            throw new IllegalArgumentException("File descriptors passed in Intent");
13463        }
13464
13465        synchronized(this) {
13466            if (!(token instanceof ServiceRecord)) {
13467                throw new IllegalArgumentException("Invalid service token");
13468            }
13469            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13470        }
13471    }
13472
13473    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
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            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13481        }
13482    }
13483
13484    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13485        synchronized(this) {
13486            if (!(token instanceof ServiceRecord)) {
13487                throw new IllegalArgumentException("Invalid service token");
13488            }
13489            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13490        }
13491    }
13492
13493    // =========================================================
13494    // BACKUP AND RESTORE
13495    // =========================================================
13496
13497    // Cause the target app to be launched if necessary and its backup agent
13498    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13499    // activity manager to announce its creation.
13500    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13501        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13502        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13503
13504        synchronized(this) {
13505            // !!! TODO: currently no check here that we're already bound
13506            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13507            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13508            synchronized (stats) {
13509                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13510            }
13511
13512            // Backup agent is now in use, its package can't be stopped.
13513            try {
13514                AppGlobals.getPackageManager().setPackageStoppedState(
13515                        app.packageName, false, UserHandle.getUserId(app.uid));
13516            } catch (RemoteException e) {
13517            } catch (IllegalArgumentException e) {
13518                Slog.w(TAG, "Failed trying to unstop package "
13519                        + app.packageName + ": " + e);
13520            }
13521
13522            BackupRecord r = new BackupRecord(ss, app, backupMode);
13523            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13524                    ? new ComponentName(app.packageName, app.backupAgentName)
13525                    : new ComponentName("android", "FullBackupAgent");
13526            // startProcessLocked() returns existing proc's record if it's already running
13527            ProcessRecord proc = startProcessLocked(app.processName, app,
13528                    false, 0, "backup", hostingName, false, false, false);
13529            if (proc == null) {
13530                Slog.e(TAG, "Unable to start backup agent process " + r);
13531                return false;
13532            }
13533
13534            r.app = proc;
13535            mBackupTarget = r;
13536            mBackupAppName = app.packageName;
13537
13538            // Try not to kill the process during backup
13539            updateOomAdjLocked(proc);
13540
13541            // If the process is already attached, schedule the creation of the backup agent now.
13542            // If it is not yet live, this will be done when it attaches to the framework.
13543            if (proc.thread != null) {
13544                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13545                try {
13546                    proc.thread.scheduleCreateBackupAgent(app,
13547                            compatibilityInfoForPackageLocked(app), backupMode);
13548                } catch (RemoteException e) {
13549                    // Will time out on the backup manager side
13550                }
13551            } else {
13552                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13553            }
13554            // Invariants: at this point, the target app process exists and the application
13555            // is either already running or in the process of coming up.  mBackupTarget and
13556            // mBackupAppName describe the app, so that when it binds back to the AM we
13557            // know that it's scheduled for a backup-agent operation.
13558        }
13559
13560        return true;
13561    }
13562
13563    @Override
13564    public void clearPendingBackup() {
13565        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13566        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13567
13568        synchronized (this) {
13569            mBackupTarget = null;
13570            mBackupAppName = null;
13571        }
13572    }
13573
13574    // A backup agent has just come up
13575    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13576        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13577                + " = " + agent);
13578
13579        synchronized(this) {
13580            if (!agentPackageName.equals(mBackupAppName)) {
13581                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13582                return;
13583            }
13584        }
13585
13586        long oldIdent = Binder.clearCallingIdentity();
13587        try {
13588            IBackupManager bm = IBackupManager.Stub.asInterface(
13589                    ServiceManager.getService(Context.BACKUP_SERVICE));
13590            bm.agentConnected(agentPackageName, agent);
13591        } catch (RemoteException e) {
13592            // can't happen; the backup manager service is local
13593        } catch (Exception e) {
13594            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13595            e.printStackTrace();
13596        } finally {
13597            Binder.restoreCallingIdentity(oldIdent);
13598        }
13599    }
13600
13601    // done with this agent
13602    public void unbindBackupAgent(ApplicationInfo appInfo) {
13603        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13604        if (appInfo == null) {
13605            Slog.w(TAG, "unbind backup agent for null app");
13606            return;
13607        }
13608
13609        synchronized(this) {
13610            try {
13611                if (mBackupAppName == null) {
13612                    Slog.w(TAG, "Unbinding backup agent with no active backup");
13613                    return;
13614                }
13615
13616                if (!mBackupAppName.equals(appInfo.packageName)) {
13617                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
13618                    return;
13619                }
13620
13621                // Not backing this app up any more; reset its OOM adjustment
13622                final ProcessRecord proc = mBackupTarget.app;
13623                updateOomAdjLocked(proc);
13624
13625                // If the app crashed during backup, 'thread' will be null here
13626                if (proc.thread != null) {
13627                    try {
13628                        proc.thread.scheduleDestroyBackupAgent(appInfo,
13629                                compatibilityInfoForPackageLocked(appInfo));
13630                    } catch (Exception e) {
13631                        Slog.e(TAG, "Exception when unbinding backup agent:");
13632                        e.printStackTrace();
13633                    }
13634                }
13635            } finally {
13636                mBackupTarget = null;
13637                mBackupAppName = null;
13638            }
13639        }
13640    }
13641    // =========================================================
13642    // BROADCASTS
13643    // =========================================================
13644
13645    private final List getStickiesLocked(String action, IntentFilter filter,
13646            List cur, int userId) {
13647        final ContentResolver resolver = mContext.getContentResolver();
13648        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
13649        if (stickies == null) {
13650            return cur;
13651        }
13652        final ArrayList<Intent> list = stickies.get(action);
13653        if (list == null) {
13654            return cur;
13655        }
13656        int N = list.size();
13657        for (int i=0; i<N; i++) {
13658            Intent intent = list.get(i);
13659            if (filter.match(resolver, intent, true, TAG) >= 0) {
13660                if (cur == null) {
13661                    cur = new ArrayList<Intent>();
13662                }
13663                cur.add(intent);
13664            }
13665        }
13666        return cur;
13667    }
13668
13669    boolean isPendingBroadcastProcessLocked(int pid) {
13670        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
13671                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
13672    }
13673
13674    void skipPendingBroadcastLocked(int pid) {
13675            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
13676            for (BroadcastQueue queue : mBroadcastQueues) {
13677                queue.skipPendingBroadcastLocked(pid);
13678            }
13679    }
13680
13681    // The app just attached; send any pending broadcasts that it should receive
13682    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
13683        boolean didSomething = false;
13684        for (BroadcastQueue queue : mBroadcastQueues) {
13685            didSomething |= queue.sendPendingBroadcastsLocked(app);
13686        }
13687        return didSomething;
13688    }
13689
13690    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
13691            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
13692        enforceNotIsolatedCaller("registerReceiver");
13693        int callingUid;
13694        int callingPid;
13695        synchronized(this) {
13696            ProcessRecord callerApp = null;
13697            if (caller != null) {
13698                callerApp = getRecordForAppLocked(caller);
13699                if (callerApp == null) {
13700                    throw new SecurityException(
13701                            "Unable to find app for caller " + caller
13702                            + " (pid=" + Binder.getCallingPid()
13703                            + ") when registering receiver " + receiver);
13704                }
13705                if (callerApp.info.uid != Process.SYSTEM_UID &&
13706                        !callerApp.pkgList.containsKey(callerPackage) &&
13707                        !"android".equals(callerPackage)) {
13708                    throw new SecurityException("Given caller package " + callerPackage
13709                            + " is not running in process " + callerApp);
13710                }
13711                callingUid = callerApp.info.uid;
13712                callingPid = callerApp.pid;
13713            } else {
13714                callerPackage = null;
13715                callingUid = Binder.getCallingUid();
13716                callingPid = Binder.getCallingPid();
13717            }
13718
13719            userId = this.handleIncomingUser(callingPid, callingUid, userId,
13720                    true, true, "registerReceiver", callerPackage);
13721
13722            List allSticky = null;
13723
13724            // Look for any matching sticky broadcasts...
13725            Iterator actions = filter.actionsIterator();
13726            if (actions != null) {
13727                while (actions.hasNext()) {
13728                    String action = (String)actions.next();
13729                    allSticky = getStickiesLocked(action, filter, allSticky,
13730                            UserHandle.USER_ALL);
13731                    allSticky = getStickiesLocked(action, filter, allSticky,
13732                            UserHandle.getUserId(callingUid));
13733                }
13734            } else {
13735                allSticky = getStickiesLocked(null, filter, allSticky,
13736                        UserHandle.USER_ALL);
13737                allSticky = getStickiesLocked(null, filter, allSticky,
13738                        UserHandle.getUserId(callingUid));
13739            }
13740
13741            // The first sticky in the list is returned directly back to
13742            // the client.
13743            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
13744
13745            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
13746                    + ": " + sticky);
13747
13748            if (receiver == null) {
13749                return sticky;
13750            }
13751
13752            ReceiverList rl
13753                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
13754            if (rl == null) {
13755                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
13756                        userId, receiver);
13757                if (rl.app != null) {
13758                    rl.app.receivers.add(rl);
13759                } else {
13760                    try {
13761                        receiver.asBinder().linkToDeath(rl, 0);
13762                    } catch (RemoteException e) {
13763                        return sticky;
13764                    }
13765                    rl.linkedToDeath = true;
13766                }
13767                mRegisteredReceivers.put(receiver.asBinder(), rl);
13768            } else if (rl.uid != callingUid) {
13769                throw new IllegalArgumentException(
13770                        "Receiver requested to register for uid " + callingUid
13771                        + " was previously registered for uid " + rl.uid);
13772            } else if (rl.pid != callingPid) {
13773                throw new IllegalArgumentException(
13774                        "Receiver requested to register for pid " + callingPid
13775                        + " was previously registered for pid " + rl.pid);
13776            } else if (rl.userId != userId) {
13777                throw new IllegalArgumentException(
13778                        "Receiver requested to register for user " + userId
13779                        + " was previously registered for user " + rl.userId);
13780            }
13781            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
13782                    permission, callingUid, userId);
13783            rl.add(bf);
13784            if (!bf.debugCheck()) {
13785                Slog.w(TAG, "==> For Dynamic broadast");
13786            }
13787            mReceiverResolver.addFilter(bf);
13788
13789            // Enqueue broadcasts for all existing stickies that match
13790            // this filter.
13791            if (allSticky != null) {
13792                ArrayList receivers = new ArrayList();
13793                receivers.add(bf);
13794
13795                int N = allSticky.size();
13796                for (int i=0; i<N; i++) {
13797                    Intent intent = (Intent)allSticky.get(i);
13798                    BroadcastQueue queue = broadcastQueueForIntent(intent);
13799                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
13800                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
13801                            null, null, false, true, true, -1);
13802                    queue.enqueueParallelBroadcastLocked(r);
13803                    queue.scheduleBroadcastsLocked();
13804                }
13805            }
13806
13807            return sticky;
13808        }
13809    }
13810
13811    public void unregisterReceiver(IIntentReceiver receiver) {
13812        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
13813
13814        final long origId = Binder.clearCallingIdentity();
13815        try {
13816            boolean doTrim = false;
13817
13818            synchronized(this) {
13819                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
13820                if (rl != null) {
13821                    if (rl.curBroadcast != null) {
13822                        BroadcastRecord r = rl.curBroadcast;
13823                        final boolean doNext = finishReceiverLocked(
13824                                receiver.asBinder(), r.resultCode, r.resultData,
13825                                r.resultExtras, r.resultAbort);
13826                        if (doNext) {
13827                            doTrim = true;
13828                            r.queue.processNextBroadcast(false);
13829                        }
13830                    }
13831
13832                    if (rl.app != null) {
13833                        rl.app.receivers.remove(rl);
13834                    }
13835                    removeReceiverLocked(rl);
13836                    if (rl.linkedToDeath) {
13837                        rl.linkedToDeath = false;
13838                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
13839                    }
13840                }
13841            }
13842
13843            // If we actually concluded any broadcasts, we might now be able
13844            // to trim the recipients' apps from our working set
13845            if (doTrim) {
13846                trimApplications();
13847                return;
13848            }
13849
13850        } finally {
13851            Binder.restoreCallingIdentity(origId);
13852        }
13853    }
13854
13855    void removeReceiverLocked(ReceiverList rl) {
13856        mRegisteredReceivers.remove(rl.receiver.asBinder());
13857        int N = rl.size();
13858        for (int i=0; i<N; i++) {
13859            mReceiverResolver.removeFilter(rl.get(i));
13860        }
13861    }
13862
13863    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
13864        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13865            ProcessRecord r = mLruProcesses.get(i);
13866            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
13867                try {
13868                    r.thread.dispatchPackageBroadcast(cmd, packages);
13869                } catch (RemoteException ex) {
13870                }
13871            }
13872        }
13873    }
13874
13875    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
13876            int[] users) {
13877        List<ResolveInfo> receivers = null;
13878        try {
13879            HashSet<ComponentName> singleUserReceivers = null;
13880            boolean scannedFirstReceivers = false;
13881            for (int user : users) {
13882                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
13883                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
13884                if (user != 0 && newReceivers != null) {
13885                    // If this is not the primary user, we need to check for
13886                    // any receivers that should be filtered out.
13887                    for (int i=0; i<newReceivers.size(); i++) {
13888                        ResolveInfo ri = newReceivers.get(i);
13889                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
13890                            newReceivers.remove(i);
13891                            i--;
13892                        }
13893                    }
13894                }
13895                if (newReceivers != null && newReceivers.size() == 0) {
13896                    newReceivers = null;
13897                }
13898                if (receivers == null) {
13899                    receivers = newReceivers;
13900                } else if (newReceivers != null) {
13901                    // We need to concatenate the additional receivers
13902                    // found with what we have do far.  This would be easy,
13903                    // but we also need to de-dup any receivers that are
13904                    // singleUser.
13905                    if (!scannedFirstReceivers) {
13906                        // Collect any single user receivers we had already retrieved.
13907                        scannedFirstReceivers = true;
13908                        for (int i=0; i<receivers.size(); i++) {
13909                            ResolveInfo ri = receivers.get(i);
13910                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
13911                                ComponentName cn = new ComponentName(
13912                                        ri.activityInfo.packageName, ri.activityInfo.name);
13913                                if (singleUserReceivers == null) {
13914                                    singleUserReceivers = new HashSet<ComponentName>();
13915                                }
13916                                singleUserReceivers.add(cn);
13917                            }
13918                        }
13919                    }
13920                    // Add the new results to the existing results, tracking
13921                    // and de-dupping single user receivers.
13922                    for (int i=0; i<newReceivers.size(); i++) {
13923                        ResolveInfo ri = newReceivers.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                            if (!singleUserReceivers.contains(cn)) {
13931                                singleUserReceivers.add(cn);
13932                                receivers.add(ri);
13933                            }
13934                        } else {
13935                            receivers.add(ri);
13936                        }
13937                    }
13938                }
13939            }
13940        } catch (RemoteException ex) {
13941            // pm is in same process, this will never happen.
13942        }
13943        return receivers;
13944    }
13945
13946    private final int broadcastIntentLocked(ProcessRecord callerApp,
13947            String callerPackage, Intent intent, String resolvedType,
13948            IIntentReceiver resultTo, int resultCode, String resultData,
13949            Bundle map, String requiredPermission, int appOp,
13950            boolean ordered, boolean sticky, int callingPid, int callingUid,
13951            int userId) {
13952        intent = new Intent(intent);
13953
13954        // By default broadcasts do not go to stopped apps.
13955        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
13956
13957        if (DEBUG_BROADCAST_LIGHT) Slog.v(
13958            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
13959            + " ordered=" + ordered + " userid=" + userId);
13960        if ((resultTo != null) && !ordered) {
13961            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
13962        }
13963
13964        userId = handleIncomingUser(callingPid, callingUid, userId,
13965                true, false, "broadcast", callerPackage);
13966
13967        // Make sure that the user who is receiving this broadcast is started.
13968        // If not, we will just skip it.
13969
13970
13971        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
13972            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
13973                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
13974                Slog.w(TAG, "Skipping broadcast of " + intent
13975                        + ": user " + userId + " is stopped");
13976                return ActivityManager.BROADCAST_SUCCESS;
13977            }
13978        }
13979
13980        /*
13981         * Prevent non-system code (defined here to be non-persistent
13982         * processes) from sending protected broadcasts.
13983         */
13984        int callingAppId = UserHandle.getAppId(callingUid);
13985        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
13986            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
13987            || callingAppId == Process.NFC_UID || callingUid == 0) {
13988            // Always okay.
13989        } else if (callerApp == null || !callerApp.persistent) {
13990            try {
13991                if (AppGlobals.getPackageManager().isProtectedBroadcast(
13992                        intent.getAction())) {
13993                    String msg = "Permission Denial: not allowed to send broadcast "
13994                            + intent.getAction() + " from pid="
13995                            + callingPid + ", uid=" + callingUid;
13996                    Slog.w(TAG, msg);
13997                    throw new SecurityException(msg);
13998                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
13999                    // Special case for compatibility: we don't want apps to send this,
14000                    // but historically it has not been protected and apps may be using it
14001                    // to poke their own app widget.  So, instead of making it protected,
14002                    // just limit it to the caller.
14003                    if (callerApp == null) {
14004                        String msg = "Permission Denial: not allowed to send broadcast "
14005                                + intent.getAction() + " from unknown caller.";
14006                        Slog.w(TAG, msg);
14007                        throw new SecurityException(msg);
14008                    } else if (intent.getComponent() != null) {
14009                        // They are good enough to send to an explicit component...  verify
14010                        // it is being sent to the calling app.
14011                        if (!intent.getComponent().getPackageName().equals(
14012                                callerApp.info.packageName)) {
14013                            String msg = "Permission Denial: not allowed to send broadcast "
14014                                    + intent.getAction() + " to "
14015                                    + intent.getComponent().getPackageName() + " from "
14016                                    + callerApp.info.packageName;
14017                            Slog.w(TAG, msg);
14018                            throw new SecurityException(msg);
14019                        }
14020                    } else {
14021                        // Limit broadcast to their own package.
14022                        intent.setPackage(callerApp.info.packageName);
14023                    }
14024                }
14025            } catch (RemoteException e) {
14026                Slog.w(TAG, "Remote exception", e);
14027                return ActivityManager.BROADCAST_SUCCESS;
14028            }
14029        }
14030
14031        // Handle special intents: if this broadcast is from the package
14032        // manager about a package being removed, we need to remove all of
14033        // its activities from the history stack.
14034        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14035                intent.getAction());
14036        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14037                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14038                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14039                || uidRemoved) {
14040            if (checkComponentPermission(
14041                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14042                    callingPid, callingUid, -1, true)
14043                    == PackageManager.PERMISSION_GRANTED) {
14044                if (uidRemoved) {
14045                    final Bundle intentExtras = intent.getExtras();
14046                    final int uid = intentExtras != null
14047                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14048                    if (uid >= 0) {
14049                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14050                        synchronized (bs) {
14051                            bs.removeUidStatsLocked(uid);
14052                        }
14053                        mAppOpsService.uidRemoved(uid);
14054                    }
14055                } else {
14056                    // If resources are unavailable just force stop all
14057                    // those packages and flush the attribute cache as well.
14058                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14059                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14060                        if (list != null && (list.length > 0)) {
14061                            for (String pkg : list) {
14062                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14063                                        "storage unmount");
14064                            }
14065                            sendPackageBroadcastLocked(
14066                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14067                        }
14068                    } else {
14069                        Uri data = intent.getData();
14070                        String ssp;
14071                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14072                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14073                                    intent.getAction());
14074                            boolean fullUninstall = removed &&
14075                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14076                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14077                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14078                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14079                                        false, fullUninstall, userId,
14080                                        removed ? "pkg removed" : "pkg changed");
14081                            }
14082                            if (removed) {
14083                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14084                                        new String[] {ssp}, userId);
14085                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14086                                    mAppOpsService.packageRemoved(
14087                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14088
14089                                    // Remove all permissions granted from/to this package
14090                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14091                                }
14092                            }
14093                        }
14094                    }
14095                }
14096            } else {
14097                String msg = "Permission Denial: " + intent.getAction()
14098                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14099                        + ", uid=" + callingUid + ")"
14100                        + " requires "
14101                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14102                Slog.w(TAG, msg);
14103                throw new SecurityException(msg);
14104            }
14105
14106        // Special case for adding a package: by default turn on compatibility
14107        // mode.
14108        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14109            Uri data = intent.getData();
14110            String ssp;
14111            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14112                mCompatModePackages.handlePackageAddedLocked(ssp,
14113                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14114            }
14115        }
14116
14117        /*
14118         * If this is the time zone changed action, queue up a message that will reset the timezone
14119         * of all currently running processes. This message will get queued up before the broadcast
14120         * happens.
14121         */
14122        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14123            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14124        }
14125
14126        /*
14127         * If the user set the time, let all running processes know.
14128         */
14129        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14130            final int is24Hour = intent.getBooleanExtra(
14131                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14132            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14133        }
14134
14135        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14136            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14137        }
14138
14139        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14140            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14141            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14142        }
14143
14144        // Add to the sticky list if requested.
14145        if (sticky) {
14146            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14147                    callingPid, callingUid)
14148                    != PackageManager.PERMISSION_GRANTED) {
14149                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14150                        + callingPid + ", uid=" + callingUid
14151                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14152                Slog.w(TAG, msg);
14153                throw new SecurityException(msg);
14154            }
14155            if (requiredPermission != null) {
14156                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14157                        + " and enforce permission " + requiredPermission);
14158                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14159            }
14160            if (intent.getComponent() != null) {
14161                throw new SecurityException(
14162                        "Sticky broadcasts can't target a specific component");
14163            }
14164            // We use userId directly here, since the "all" target is maintained
14165            // as a separate set of sticky broadcasts.
14166            if (userId != UserHandle.USER_ALL) {
14167                // But first, if this is not a broadcast to all users, then
14168                // make sure it doesn't conflict with an existing broadcast to
14169                // all users.
14170                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14171                        UserHandle.USER_ALL);
14172                if (stickies != null) {
14173                    ArrayList<Intent> list = stickies.get(intent.getAction());
14174                    if (list != null) {
14175                        int N = list.size();
14176                        int i;
14177                        for (i=0; i<N; i++) {
14178                            if (intent.filterEquals(list.get(i))) {
14179                                throw new IllegalArgumentException(
14180                                        "Sticky broadcast " + intent + " for user "
14181                                        + userId + " conflicts with existing global broadcast");
14182                            }
14183                        }
14184                    }
14185                }
14186            }
14187            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14188            if (stickies == null) {
14189                stickies = new ArrayMap<String, ArrayList<Intent>>();
14190                mStickyBroadcasts.put(userId, stickies);
14191            }
14192            ArrayList<Intent> list = stickies.get(intent.getAction());
14193            if (list == null) {
14194                list = new ArrayList<Intent>();
14195                stickies.put(intent.getAction(), list);
14196            }
14197            int N = list.size();
14198            int i;
14199            for (i=0; i<N; i++) {
14200                if (intent.filterEquals(list.get(i))) {
14201                    // This sticky already exists, replace it.
14202                    list.set(i, new Intent(intent));
14203                    break;
14204                }
14205            }
14206            if (i >= N) {
14207                list.add(new Intent(intent));
14208            }
14209        }
14210
14211        int[] users;
14212        if (userId == UserHandle.USER_ALL) {
14213            // Caller wants broadcast to go to all started users.
14214            users = mStartedUserArray;
14215        } else {
14216            // Caller wants broadcast to go to one specific user.
14217            users = new int[] {userId};
14218        }
14219
14220        // Figure out who all will receive this broadcast.
14221        List receivers = null;
14222        List<BroadcastFilter> registeredReceivers = null;
14223        // Need to resolve the intent to interested receivers...
14224        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14225                 == 0) {
14226            receivers = collectReceiverComponents(intent, resolvedType, users);
14227        }
14228        if (intent.getComponent() == null) {
14229            registeredReceivers = mReceiverResolver.queryIntent(intent,
14230                    resolvedType, false, userId);
14231        }
14232
14233        final boolean replacePending =
14234                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14235
14236        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14237                + " replacePending=" + replacePending);
14238
14239        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14240        if (!ordered && NR > 0) {
14241            // If we are not serializing this broadcast, then send the
14242            // registered receivers separately so they don't wait for the
14243            // components to be launched.
14244            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14245            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14246                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14247                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14248                    ordered, sticky, false, userId);
14249            if (DEBUG_BROADCAST) Slog.v(
14250                    TAG, "Enqueueing parallel broadcast " + r);
14251            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14252            if (!replaced) {
14253                queue.enqueueParallelBroadcastLocked(r);
14254                queue.scheduleBroadcastsLocked();
14255            }
14256            registeredReceivers = null;
14257            NR = 0;
14258        }
14259
14260        // Merge into one list.
14261        int ir = 0;
14262        if (receivers != null) {
14263            // A special case for PACKAGE_ADDED: do not allow the package
14264            // being added to see this broadcast.  This prevents them from
14265            // using this as a back door to get run as soon as they are
14266            // installed.  Maybe in the future we want to have a special install
14267            // broadcast or such for apps, but we'd like to deliberately make
14268            // this decision.
14269            String skipPackages[] = null;
14270            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14271                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14272                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14273                Uri data = intent.getData();
14274                if (data != null) {
14275                    String pkgName = data.getSchemeSpecificPart();
14276                    if (pkgName != null) {
14277                        skipPackages = new String[] { pkgName };
14278                    }
14279                }
14280            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14281                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14282            }
14283            if (skipPackages != null && (skipPackages.length > 0)) {
14284                for (String skipPackage : skipPackages) {
14285                    if (skipPackage != null) {
14286                        int NT = receivers.size();
14287                        for (int it=0; it<NT; it++) {
14288                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14289                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14290                                receivers.remove(it);
14291                                it--;
14292                                NT--;
14293                            }
14294                        }
14295                    }
14296                }
14297            }
14298
14299            int NT = receivers != null ? receivers.size() : 0;
14300            int it = 0;
14301            ResolveInfo curt = null;
14302            BroadcastFilter curr = null;
14303            while (it < NT && ir < NR) {
14304                if (curt == null) {
14305                    curt = (ResolveInfo)receivers.get(it);
14306                }
14307                if (curr == null) {
14308                    curr = registeredReceivers.get(ir);
14309                }
14310                if (curr.getPriority() >= curt.priority) {
14311                    // Insert this broadcast record into the final list.
14312                    receivers.add(it, curr);
14313                    ir++;
14314                    curr = null;
14315                    it++;
14316                    NT++;
14317                } else {
14318                    // Skip to the next ResolveInfo in the final list.
14319                    it++;
14320                    curt = null;
14321                }
14322            }
14323        }
14324        while (ir < NR) {
14325            if (receivers == null) {
14326                receivers = new ArrayList();
14327            }
14328            receivers.add(registeredReceivers.get(ir));
14329            ir++;
14330        }
14331
14332        if ((receivers != null && receivers.size() > 0)
14333                || resultTo != null) {
14334            BroadcastQueue queue = broadcastQueueForIntent(intent);
14335            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14336                    callerPackage, callingPid, callingUid, resolvedType,
14337                    requiredPermission, appOp, receivers, resultTo, resultCode,
14338                    resultData, map, ordered, sticky, false, userId);
14339            if (DEBUG_BROADCAST) Slog.v(
14340                    TAG, "Enqueueing ordered broadcast " + r
14341                    + ": prev had " + queue.mOrderedBroadcasts.size());
14342            if (DEBUG_BROADCAST) {
14343                int seq = r.intent.getIntExtra("seq", -1);
14344                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14345            }
14346            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14347            if (!replaced) {
14348                queue.enqueueOrderedBroadcastLocked(r);
14349                queue.scheduleBroadcastsLocked();
14350            }
14351        }
14352
14353        return ActivityManager.BROADCAST_SUCCESS;
14354    }
14355
14356    final Intent verifyBroadcastLocked(Intent intent) {
14357        // Refuse possible leaked file descriptors
14358        if (intent != null && intent.hasFileDescriptors() == true) {
14359            throw new IllegalArgumentException("File descriptors passed in Intent");
14360        }
14361
14362        int flags = intent.getFlags();
14363
14364        if (!mProcessesReady) {
14365            // if the caller really truly claims to know what they're doing, go
14366            // ahead and allow the broadcast without launching any receivers
14367            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14368                intent = new Intent(intent);
14369                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14370            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14371                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14372                        + " before boot completion");
14373                throw new IllegalStateException("Cannot broadcast before boot completed");
14374            }
14375        }
14376
14377        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14378            throw new IllegalArgumentException(
14379                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14380        }
14381
14382        return intent;
14383    }
14384
14385    public final int broadcastIntent(IApplicationThread caller,
14386            Intent intent, String resolvedType, IIntentReceiver resultTo,
14387            int resultCode, String resultData, Bundle map,
14388            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14389        enforceNotIsolatedCaller("broadcastIntent");
14390        synchronized(this) {
14391            intent = verifyBroadcastLocked(intent);
14392
14393            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14394            final int callingPid = Binder.getCallingPid();
14395            final int callingUid = Binder.getCallingUid();
14396            final long origId = Binder.clearCallingIdentity();
14397            int res = broadcastIntentLocked(callerApp,
14398                    callerApp != null ? callerApp.info.packageName : null,
14399                    intent, resolvedType, resultTo,
14400                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14401                    callingPid, callingUid, userId);
14402            Binder.restoreCallingIdentity(origId);
14403            return res;
14404        }
14405    }
14406
14407    int broadcastIntentInPackage(String packageName, int uid,
14408            Intent intent, String resolvedType, IIntentReceiver resultTo,
14409            int resultCode, String resultData, Bundle map,
14410            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14411        synchronized(this) {
14412            intent = verifyBroadcastLocked(intent);
14413
14414            final long origId = Binder.clearCallingIdentity();
14415            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14416                    resultTo, resultCode, resultData, map, requiredPermission,
14417                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14418            Binder.restoreCallingIdentity(origId);
14419            return res;
14420        }
14421    }
14422
14423    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14424        // Refuse possible leaked file descriptors
14425        if (intent != null && intent.hasFileDescriptors() == true) {
14426            throw new IllegalArgumentException("File descriptors passed in Intent");
14427        }
14428
14429        userId = handleIncomingUser(Binder.getCallingPid(),
14430                Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
14431
14432        synchronized(this) {
14433            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14434                    != PackageManager.PERMISSION_GRANTED) {
14435                String msg = "Permission Denial: unbroadcastIntent() from pid="
14436                        + Binder.getCallingPid()
14437                        + ", uid=" + Binder.getCallingUid()
14438                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14439                Slog.w(TAG, msg);
14440                throw new SecurityException(msg);
14441            }
14442            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14443            if (stickies != null) {
14444                ArrayList<Intent> list = stickies.get(intent.getAction());
14445                if (list != null) {
14446                    int N = list.size();
14447                    int i;
14448                    for (i=0; i<N; i++) {
14449                        if (intent.filterEquals(list.get(i))) {
14450                            list.remove(i);
14451                            break;
14452                        }
14453                    }
14454                    if (list.size() <= 0) {
14455                        stickies.remove(intent.getAction());
14456                    }
14457                }
14458                if (stickies.size() <= 0) {
14459                    mStickyBroadcasts.remove(userId);
14460                }
14461            }
14462        }
14463    }
14464
14465    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14466            String resultData, Bundle resultExtras, boolean resultAbort) {
14467        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14468        if (r == null) {
14469            Slog.w(TAG, "finishReceiver called but not found on queue");
14470            return false;
14471        }
14472
14473        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14474    }
14475
14476    void backgroundServicesFinishedLocked(int userId) {
14477        for (BroadcastQueue queue : mBroadcastQueues) {
14478            queue.backgroundServicesFinishedLocked(userId);
14479        }
14480    }
14481
14482    public void finishReceiver(IBinder who, int resultCode, String resultData,
14483            Bundle resultExtras, boolean resultAbort) {
14484        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14485
14486        // Refuse possible leaked file descriptors
14487        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14488            throw new IllegalArgumentException("File descriptors passed in Bundle");
14489        }
14490
14491        final long origId = Binder.clearCallingIdentity();
14492        try {
14493            boolean doNext = false;
14494            BroadcastRecord r;
14495
14496            synchronized(this) {
14497                r = broadcastRecordForReceiverLocked(who);
14498                if (r != null) {
14499                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14500                        resultData, resultExtras, resultAbort, true);
14501                }
14502            }
14503
14504            if (doNext) {
14505                r.queue.processNextBroadcast(false);
14506            }
14507            trimApplications();
14508        } finally {
14509            Binder.restoreCallingIdentity(origId);
14510        }
14511    }
14512
14513    // =========================================================
14514    // INSTRUMENTATION
14515    // =========================================================
14516
14517    public boolean startInstrumentation(ComponentName className,
14518            String profileFile, int flags, Bundle arguments,
14519            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14520            int userId, String abiOverride) {
14521        enforceNotIsolatedCaller("startInstrumentation");
14522        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14523                userId, false, true, "startInstrumentation", null);
14524        // Refuse possible leaked file descriptors
14525        if (arguments != null && arguments.hasFileDescriptors()) {
14526            throw new IllegalArgumentException("File descriptors passed in Bundle");
14527        }
14528
14529        synchronized(this) {
14530            InstrumentationInfo ii = null;
14531            ApplicationInfo ai = null;
14532            try {
14533                ii = mContext.getPackageManager().getInstrumentationInfo(
14534                    className, STOCK_PM_FLAGS);
14535                ai = AppGlobals.getPackageManager().getApplicationInfo(
14536                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14537            } catch (PackageManager.NameNotFoundException e) {
14538            } catch (RemoteException e) {
14539            }
14540            if (ii == null) {
14541                reportStartInstrumentationFailure(watcher, className,
14542                        "Unable to find instrumentation info for: " + className);
14543                return false;
14544            }
14545            if (ai == null) {
14546                reportStartInstrumentationFailure(watcher, className,
14547                        "Unable to find instrumentation target package: " + ii.targetPackage);
14548                return false;
14549            }
14550
14551            int match = mContext.getPackageManager().checkSignatures(
14552                    ii.targetPackage, ii.packageName);
14553            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14554                String msg = "Permission Denial: starting instrumentation "
14555                        + className + " from pid="
14556                        + Binder.getCallingPid()
14557                        + ", uid=" + Binder.getCallingPid()
14558                        + " not allowed because package " + ii.packageName
14559                        + " does not have a signature matching the target "
14560                        + ii.targetPackage;
14561                reportStartInstrumentationFailure(watcher, className, msg);
14562                throw new SecurityException(msg);
14563            }
14564
14565            final long origId = Binder.clearCallingIdentity();
14566            // Instrumentation can kill and relaunch even persistent processes
14567            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14568                    "start instr");
14569            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14570            app.instrumentationClass = className;
14571            app.instrumentationInfo = ai;
14572            app.instrumentationProfileFile = profileFile;
14573            app.instrumentationArguments = arguments;
14574            app.instrumentationWatcher = watcher;
14575            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14576            app.instrumentationResultClass = className;
14577            Binder.restoreCallingIdentity(origId);
14578        }
14579
14580        return true;
14581    }
14582
14583    /**
14584     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14585     * error to the logs, but if somebody is watching, send the report there too.  This enables
14586     * the "am" command to report errors with more information.
14587     *
14588     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14589     * @param cn The component name of the instrumentation.
14590     * @param report The error report.
14591     */
14592    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14593            ComponentName cn, String report) {
14594        Slog.w(TAG, report);
14595        try {
14596            if (watcher != null) {
14597                Bundle results = new Bundle();
14598                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14599                results.putString("Error", report);
14600                watcher.instrumentationStatus(cn, -1, results);
14601            }
14602        } catch (RemoteException e) {
14603            Slog.w(TAG, e);
14604        }
14605    }
14606
14607    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
14608        if (app.instrumentationWatcher != null) {
14609            try {
14610                // NOTE:  IInstrumentationWatcher *must* be oneway here
14611                app.instrumentationWatcher.instrumentationFinished(
14612                    app.instrumentationClass,
14613                    resultCode,
14614                    results);
14615            } catch (RemoteException e) {
14616            }
14617        }
14618        if (app.instrumentationUiAutomationConnection != null) {
14619            try {
14620                app.instrumentationUiAutomationConnection.shutdown();
14621            } catch (RemoteException re) {
14622                /* ignore */
14623            }
14624            // Only a UiAutomation can set this flag and now that
14625            // it is finished we make sure it is reset to its default.
14626            mUserIsMonkey = false;
14627        }
14628        app.instrumentationWatcher = null;
14629        app.instrumentationUiAutomationConnection = null;
14630        app.instrumentationClass = null;
14631        app.instrumentationInfo = null;
14632        app.instrumentationProfileFile = null;
14633        app.instrumentationArguments = null;
14634
14635        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
14636                "finished inst");
14637    }
14638
14639    public void finishInstrumentation(IApplicationThread target,
14640            int resultCode, Bundle results) {
14641        int userId = UserHandle.getCallingUserId();
14642        // Refuse possible leaked file descriptors
14643        if (results != null && results.hasFileDescriptors()) {
14644            throw new IllegalArgumentException("File descriptors passed in Intent");
14645        }
14646
14647        synchronized(this) {
14648            ProcessRecord app = getRecordForAppLocked(target);
14649            if (app == null) {
14650                Slog.w(TAG, "finishInstrumentation: no app for " + target);
14651                return;
14652            }
14653            final long origId = Binder.clearCallingIdentity();
14654            finishInstrumentationLocked(app, resultCode, results);
14655            Binder.restoreCallingIdentity(origId);
14656        }
14657    }
14658
14659    // =========================================================
14660    // CONFIGURATION
14661    // =========================================================
14662
14663    public ConfigurationInfo getDeviceConfigurationInfo() {
14664        ConfigurationInfo config = new ConfigurationInfo();
14665        synchronized (this) {
14666            config.reqTouchScreen = mConfiguration.touchscreen;
14667            config.reqKeyboardType = mConfiguration.keyboard;
14668            config.reqNavigation = mConfiguration.navigation;
14669            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
14670                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
14671                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
14672            }
14673            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
14674                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
14675                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
14676            }
14677            config.reqGlEsVersion = GL_ES_VERSION;
14678        }
14679        return config;
14680    }
14681
14682    ActivityStack getFocusedStack() {
14683        return mStackSupervisor.getFocusedStack();
14684    }
14685
14686    public Configuration getConfiguration() {
14687        Configuration ci;
14688        synchronized(this) {
14689            ci = new Configuration(mConfiguration);
14690        }
14691        return ci;
14692    }
14693
14694    public void updatePersistentConfiguration(Configuration values) {
14695        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14696                "updateConfiguration()");
14697        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
14698                "updateConfiguration()");
14699        if (values == null) {
14700            throw new NullPointerException("Configuration must not be null");
14701        }
14702
14703        synchronized(this) {
14704            final long origId = Binder.clearCallingIdentity();
14705            updateConfigurationLocked(values, null, true, false);
14706            Binder.restoreCallingIdentity(origId);
14707        }
14708    }
14709
14710    public void updateConfiguration(Configuration values) {
14711        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
14712                "updateConfiguration()");
14713
14714        synchronized(this) {
14715            if (values == null && mWindowManager != null) {
14716                // sentinel: fetch the current configuration from the window manager
14717                values = mWindowManager.computeNewConfiguration();
14718            }
14719
14720            if (mWindowManager != null) {
14721                mProcessList.applyDisplaySize(mWindowManager);
14722            }
14723
14724            final long origId = Binder.clearCallingIdentity();
14725            if (values != null) {
14726                Settings.System.clearConfiguration(values);
14727            }
14728            updateConfigurationLocked(values, null, false, false);
14729            Binder.restoreCallingIdentity(origId);
14730        }
14731    }
14732
14733    /**
14734     * Do either or both things: (1) change the current configuration, and (2)
14735     * make sure the given activity is running with the (now) current
14736     * configuration.  Returns true if the activity has been left running, or
14737     * false if <var>starting</var> is being destroyed to match the new
14738     * configuration.
14739     * @param persistent TODO
14740     */
14741    boolean updateConfigurationLocked(Configuration values,
14742            ActivityRecord starting, boolean persistent, boolean initLocale) {
14743        int changes = 0;
14744
14745        if (values != null) {
14746            Configuration newConfig = new Configuration(mConfiguration);
14747            changes = newConfig.updateFrom(values);
14748            if (changes != 0) {
14749                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
14750                    Slog.i(TAG, "Updating configuration to: " + values);
14751                }
14752
14753                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
14754
14755                if (values.locale != null && !initLocale) {
14756                    saveLocaleLocked(values.locale,
14757                                     !values.locale.equals(mConfiguration.locale),
14758                                     values.userSetLocale);
14759                }
14760
14761                mConfigurationSeq++;
14762                if (mConfigurationSeq <= 0) {
14763                    mConfigurationSeq = 1;
14764                }
14765                newConfig.seq = mConfigurationSeq;
14766                mConfiguration = newConfig;
14767                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
14768                mUsageStatsService.noteStartConfig(newConfig);
14769
14770                final Configuration configCopy = new Configuration(mConfiguration);
14771
14772                // TODO: If our config changes, should we auto dismiss any currently
14773                // showing dialogs?
14774                mShowDialogs = shouldShowDialogs(newConfig);
14775
14776                AttributeCache ac = AttributeCache.instance();
14777                if (ac != null) {
14778                    ac.updateConfiguration(configCopy);
14779                }
14780
14781                // Make sure all resources in our process are updated
14782                // right now, so that anyone who is going to retrieve
14783                // resource values after we return will be sure to get
14784                // the new ones.  This is especially important during
14785                // boot, where the first config change needs to guarantee
14786                // all resources have that config before following boot
14787                // code is executed.
14788                mSystemThread.applyConfigurationToResources(configCopy);
14789
14790                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
14791                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
14792                    msg.obj = new Configuration(configCopy);
14793                    mHandler.sendMessage(msg);
14794                }
14795
14796                for (int i=mLruProcesses.size()-1; i>=0; i--) {
14797                    ProcessRecord app = mLruProcesses.get(i);
14798                    try {
14799                        if (app.thread != null) {
14800                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
14801                                    + app.processName + " new config " + mConfiguration);
14802                            app.thread.scheduleConfigurationChanged(configCopy);
14803                        }
14804                    } catch (Exception e) {
14805                    }
14806                }
14807                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
14808                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14809                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
14810                        | Intent.FLAG_RECEIVER_FOREGROUND);
14811                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
14812                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
14813                        Process.SYSTEM_UID, UserHandle.USER_ALL);
14814                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
14815                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
14816                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
14817                    broadcastIntentLocked(null, null, intent,
14818                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
14819                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14820                }
14821            }
14822        }
14823
14824        boolean kept = true;
14825        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
14826        // mainStack is null during startup.
14827        if (mainStack != null) {
14828            if (changes != 0 && starting == null) {
14829                // If the configuration changed, and the caller is not already
14830                // in the process of starting an activity, then find the top
14831                // activity to check if its configuration needs to change.
14832                starting = mainStack.topRunningActivityLocked(null);
14833            }
14834
14835            if (starting != null) {
14836                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
14837                // And we need to make sure at this point that all other activities
14838                // are made visible with the correct configuration.
14839                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
14840            }
14841        }
14842
14843        if (values != null && mWindowManager != null) {
14844            mWindowManager.setNewConfiguration(mConfiguration);
14845        }
14846
14847        return kept;
14848    }
14849
14850    /**
14851     * Decide based on the configuration whether we should shouw the ANR,
14852     * crash, etc dialogs.  The idea is that if there is no affordnace to
14853     * press the on-screen buttons, we shouldn't show the dialog.
14854     *
14855     * A thought: SystemUI might also want to get told about this, the Power
14856     * dialog / global actions also might want different behaviors.
14857     */
14858    private static final boolean shouldShowDialogs(Configuration config) {
14859        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
14860                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
14861    }
14862
14863    /**
14864     * Save the locale.  You must be inside a synchronized (this) block.
14865     */
14866    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
14867        if(isDiff) {
14868            SystemProperties.set("user.language", l.getLanguage());
14869            SystemProperties.set("user.region", l.getCountry());
14870        }
14871
14872        if(isPersist) {
14873            SystemProperties.set("persist.sys.language", l.getLanguage());
14874            SystemProperties.set("persist.sys.country", l.getCountry());
14875            SystemProperties.set("persist.sys.localevar", l.getVariant());
14876        }
14877    }
14878
14879    @Override
14880    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
14881        ActivityRecord srec = ActivityRecord.forToken(token);
14882        return srec != null && srec.task.affinity != null &&
14883                srec.task.affinity.equals(destAffinity);
14884    }
14885
14886    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
14887            Intent resultData) {
14888
14889        synchronized (this) {
14890            final ActivityStack stack = ActivityRecord.getStackLocked(token);
14891            if (stack != null) {
14892                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
14893            }
14894            return false;
14895        }
14896    }
14897
14898    public int getLaunchedFromUid(IBinder activityToken) {
14899        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14900        if (srec == null) {
14901            return -1;
14902        }
14903        return srec.launchedFromUid;
14904    }
14905
14906    public String getLaunchedFromPackage(IBinder activityToken) {
14907        ActivityRecord srec = ActivityRecord.forToken(activityToken);
14908        if (srec == null) {
14909            return null;
14910        }
14911        return srec.launchedFromPackage;
14912    }
14913
14914    // =========================================================
14915    // LIFETIME MANAGEMENT
14916    // =========================================================
14917
14918    // Returns which broadcast queue the app is the current [or imminent] receiver
14919    // on, or 'null' if the app is not an active broadcast recipient.
14920    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
14921        BroadcastRecord r = app.curReceiver;
14922        if (r != null) {
14923            return r.queue;
14924        }
14925
14926        // It's not the current receiver, but it might be starting up to become one
14927        synchronized (this) {
14928            for (BroadcastQueue queue : mBroadcastQueues) {
14929                r = queue.mPendingBroadcast;
14930                if (r != null && r.curApp == app) {
14931                    // found it; report which queue it's in
14932                    return queue;
14933                }
14934            }
14935        }
14936
14937        return null;
14938    }
14939
14940    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
14941            boolean doingAll, long now) {
14942        if (mAdjSeq == app.adjSeq) {
14943            // This adjustment has already been computed.
14944            return app.curRawAdj;
14945        }
14946
14947        if (app.thread == null) {
14948            app.adjSeq = mAdjSeq;
14949            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
14950            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
14951            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
14952        }
14953
14954        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
14955        app.adjSource = null;
14956        app.adjTarget = null;
14957        app.empty = false;
14958        app.cached = false;
14959
14960        final int activitiesSize = app.activities.size();
14961
14962        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14963            // The max adjustment doesn't allow this app to be anything
14964            // below foreground, so it is not worth doing work for it.
14965            app.adjType = "fixed";
14966            app.adjSeq = mAdjSeq;
14967            app.curRawAdj = app.maxAdj;
14968            app.foregroundActivities = false;
14969            app.keeping = true;
14970            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
14971            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
14972            // System processes can do UI, and when they do we want to have
14973            // them trim their memory after the user leaves the UI.  To
14974            // facilitate this, here we need to determine whether or not it
14975            // is currently showing UI.
14976            app.systemNoUi = true;
14977            if (app == TOP_APP) {
14978                app.systemNoUi = false;
14979            } else if (activitiesSize > 0) {
14980                for (int j = 0; j < activitiesSize; j++) {
14981                    final ActivityRecord r = app.activities.get(j);
14982                    if (r.visible) {
14983                        app.systemNoUi = false;
14984                    }
14985                }
14986            }
14987            if (!app.systemNoUi) {
14988                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
14989            }
14990            return (app.curAdj=app.maxAdj);
14991        }
14992
14993        app.keeping = false;
14994        app.systemNoUi = false;
14995
14996        // Determine the importance of the process, starting with most
14997        // important to least, and assign an appropriate OOM adjustment.
14998        int adj;
14999        int schedGroup;
15000        int procState;
15001        boolean foregroundActivities = false;
15002        BroadcastQueue queue;
15003        if (app == TOP_APP) {
15004            // The last app on the list is the foreground app.
15005            adj = ProcessList.FOREGROUND_APP_ADJ;
15006            schedGroup = Process.THREAD_GROUP_DEFAULT;
15007            app.adjType = "top-activity";
15008            foregroundActivities = true;
15009            procState = ActivityManager.PROCESS_STATE_TOP;
15010        } else if (app.instrumentationClass != null) {
15011            // Don't want to kill running instrumentation.
15012            adj = ProcessList.FOREGROUND_APP_ADJ;
15013            schedGroup = Process.THREAD_GROUP_DEFAULT;
15014            app.adjType = "instrumentation";
15015            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15016        } else if ((queue = isReceivingBroadcast(app)) != null) {
15017            // An app that is currently receiving a broadcast also
15018            // counts as being in the foreground for OOM killer purposes.
15019            // It's placed in a sched group based on the nature of the
15020            // broadcast as reflected by which queue it's active in.
15021            adj = ProcessList.FOREGROUND_APP_ADJ;
15022            schedGroup = (queue == mFgBroadcastQueue)
15023                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15024            app.adjType = "broadcast";
15025            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15026        } else if (app.executingServices.size() > 0) {
15027            // An app that is currently executing a service callback also
15028            // counts as being in the foreground.
15029            adj = ProcessList.FOREGROUND_APP_ADJ;
15030            schedGroup = app.execServicesFg ?
15031                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15032            app.adjType = "exec-service";
15033            procState = ActivityManager.PROCESS_STATE_SERVICE;
15034            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15035        } else {
15036            // As far as we know the process is empty.  We may change our mind later.
15037            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15038            // At this point we don't actually know the adjustment.  Use the cached adj
15039            // value that the caller wants us to.
15040            adj = cachedAdj;
15041            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15042            app.cached = true;
15043            app.empty = true;
15044            app.adjType = "cch-empty";
15045        }
15046
15047        // Examine all activities if not already foreground.
15048        if (!foregroundActivities && activitiesSize > 0) {
15049            for (int j = 0; j < activitiesSize; j++) {
15050                final ActivityRecord r = app.activities.get(j);
15051                if (r.app != app) {
15052                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15053                            + app + "?!?");
15054                    continue;
15055                }
15056                if (r.visible) {
15057                    // App has a visible activity; only upgrade adjustment.
15058                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15059                        adj = ProcessList.VISIBLE_APP_ADJ;
15060                        app.adjType = "visible";
15061                    }
15062                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15063                        procState = ActivityManager.PROCESS_STATE_TOP;
15064                    }
15065                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15066                    app.cached = false;
15067                    app.empty = false;
15068                    foregroundActivities = true;
15069                    break;
15070                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15071                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15072                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15073                        app.adjType = "pausing";
15074                    }
15075                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15076                        procState = ActivityManager.PROCESS_STATE_TOP;
15077                    }
15078                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15079                    app.cached = false;
15080                    app.empty = false;
15081                    foregroundActivities = true;
15082                } else if (r.state == ActivityState.STOPPING) {
15083                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15084                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15085                        app.adjType = "stopping";
15086                    }
15087                    // For the process state, we will at this point consider the
15088                    // process to be cached.  It will be cached either as an activity
15089                    // or empty depending on whether the activity is finishing.  We do
15090                    // this so that we can treat the process as cached for purposes of
15091                    // memory trimming (determing current memory level, trim command to
15092                    // send to process) since there can be an arbitrary number of stopping
15093                    // processes and they should soon all go into the cached state.
15094                    if (!r.finishing) {
15095                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15096                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15097                        }
15098                    }
15099                    app.cached = false;
15100                    app.empty = false;
15101                    foregroundActivities = true;
15102                } else {
15103                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15104                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15105                        app.adjType = "cch-act";
15106                    }
15107                }
15108            }
15109        }
15110
15111        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15112            if (app.foregroundServices) {
15113                // The user is aware of this app, so make it visible.
15114                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15115                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15116                app.cached = false;
15117                app.adjType = "fg-service";
15118                schedGroup = Process.THREAD_GROUP_DEFAULT;
15119            } else if (app.forcingToForeground != null) {
15120                // The user is aware of this app, so make it visible.
15121                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15122                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15123                app.cached = false;
15124                app.adjType = "force-fg";
15125                app.adjSource = app.forcingToForeground;
15126                schedGroup = Process.THREAD_GROUP_DEFAULT;
15127            }
15128        }
15129
15130        if (app == mHeavyWeightProcess) {
15131            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15132                // We don't want to kill the current heavy-weight process.
15133                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15134                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15135                app.cached = false;
15136                app.adjType = "heavy";
15137            }
15138            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15139                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15140            }
15141        }
15142
15143        if (app == mHomeProcess) {
15144            if (adj > ProcessList.HOME_APP_ADJ) {
15145                // This process is hosting what we currently consider to be the
15146                // home app, so we don't want to let it go into the background.
15147                adj = ProcessList.HOME_APP_ADJ;
15148                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15149                app.cached = false;
15150                app.adjType = "home";
15151            }
15152            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15153                procState = ActivityManager.PROCESS_STATE_HOME;
15154            }
15155        }
15156
15157        if (app == mPreviousProcess && app.activities.size() > 0) {
15158            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15159                // This was the previous process that showed UI to the user.
15160                // We want to try to keep it around more aggressively, to give
15161                // a good experience around switching between two apps.
15162                adj = ProcessList.PREVIOUS_APP_ADJ;
15163                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15164                app.cached = false;
15165                app.adjType = "previous";
15166            }
15167            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15168                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15169            }
15170        }
15171
15172        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15173                + " reason=" + app.adjType);
15174
15175        // By default, we use the computed adjustment.  It may be changed if
15176        // there are applications dependent on our services or providers, but
15177        // this gives us a baseline and makes sure we don't get into an
15178        // infinite recursion.
15179        app.adjSeq = mAdjSeq;
15180        app.curRawAdj = adj;
15181        app.hasStartedServices = false;
15182
15183        if (mBackupTarget != null && app == mBackupTarget.app) {
15184            // If possible we want to avoid killing apps while they're being backed up
15185            if (adj > ProcessList.BACKUP_APP_ADJ) {
15186                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15187                adj = ProcessList.BACKUP_APP_ADJ;
15188                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15189                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15190                }
15191                app.adjType = "backup";
15192                app.cached = false;
15193            }
15194            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15195                procState = ActivityManager.PROCESS_STATE_BACKUP;
15196            }
15197        }
15198
15199        boolean mayBeTop = false;
15200
15201        for (int is = app.services.size()-1;
15202                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15203                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15204                        || procState > ActivityManager.PROCESS_STATE_TOP);
15205                is--) {
15206            ServiceRecord s = app.services.valueAt(is);
15207            if (s.startRequested) {
15208                app.hasStartedServices = true;
15209                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15210                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15211                }
15212                if (app.hasShownUi && app != mHomeProcess) {
15213                    // If this process has shown some UI, let it immediately
15214                    // go to the LRU list because it may be pretty heavy with
15215                    // UI stuff.  We'll tag it with a label just to help
15216                    // debug and understand what is going on.
15217                    if (adj > ProcessList.SERVICE_ADJ) {
15218                        app.adjType = "cch-started-ui-services";
15219                    }
15220                } else {
15221                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15222                        // This service has seen some activity within
15223                        // recent memory, so we will keep its process ahead
15224                        // of the background processes.
15225                        if (adj > ProcessList.SERVICE_ADJ) {
15226                            adj = ProcessList.SERVICE_ADJ;
15227                            app.adjType = "started-services";
15228                            app.cached = false;
15229                        }
15230                    }
15231                    // If we have let the service slide into the background
15232                    // state, still have some text describing what it is doing
15233                    // even though the service no longer has an impact.
15234                    if (adj > ProcessList.SERVICE_ADJ) {
15235                        app.adjType = "cch-started-services";
15236                    }
15237                }
15238                // Don't kill this process because it is doing work; it
15239                // has said it is doing work.
15240                app.keeping = true;
15241            }
15242            for (int conni = s.connections.size()-1;
15243                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15244                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15245                            || procState > ActivityManager.PROCESS_STATE_TOP);
15246                    conni--) {
15247                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15248                for (int i = 0;
15249                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15250                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15251                                || procState > ActivityManager.PROCESS_STATE_TOP);
15252                        i++) {
15253                    // XXX should compute this based on the max of
15254                    // all connected clients.
15255                    ConnectionRecord cr = clist.get(i);
15256                    if (cr.binding.client == app) {
15257                        // Binding to ourself is not interesting.
15258                        continue;
15259                    }
15260                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15261                        ProcessRecord client = cr.binding.client;
15262                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15263                                TOP_APP, doingAll, now);
15264                        int clientProcState = client.curProcState;
15265                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15266                            // If the other app is cached for any reason, for purposes here
15267                            // we are going to consider it empty.  The specific cached state
15268                            // doesn't propagate except under certain conditions.
15269                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15270                        }
15271                        String adjType = null;
15272                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15273                            // Not doing bind OOM management, so treat
15274                            // this guy more like a started service.
15275                            if (app.hasShownUi && app != mHomeProcess) {
15276                                // If this process has shown some UI, let it immediately
15277                                // go to the LRU list because it may be pretty heavy with
15278                                // UI stuff.  We'll tag it with a label just to help
15279                                // debug and understand what is going on.
15280                                if (adj > clientAdj) {
15281                                    adjType = "cch-bound-ui-services";
15282                                }
15283                                app.cached = false;
15284                                clientAdj = adj;
15285                                clientProcState = procState;
15286                            } else {
15287                                if (now >= (s.lastActivity
15288                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15289                                    // This service has not seen activity within
15290                                    // recent memory, so allow it to drop to the
15291                                    // LRU list if there is no other reason to keep
15292                                    // it around.  We'll also tag it with a label just
15293                                    // to help debug and undertand what is going on.
15294                                    if (adj > clientAdj) {
15295                                        adjType = "cch-bound-services";
15296                                    }
15297                                    clientAdj = adj;
15298                                }
15299                            }
15300                        }
15301                        if (adj > clientAdj) {
15302                            // If this process has recently shown UI, and
15303                            // the process that is binding to it is less
15304                            // important than being visible, then we don't
15305                            // care about the binding as much as we care
15306                            // about letting this process get into the LRU
15307                            // list to be killed and restarted if needed for
15308                            // memory.
15309                            if (app.hasShownUi && app != mHomeProcess
15310                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15311                                adjType = "cch-bound-ui-services";
15312                            } else {
15313                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15314                                        |Context.BIND_IMPORTANT)) != 0) {
15315                                    adj = clientAdj;
15316                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15317                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15318                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15319                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15320                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15321                                    adj = clientAdj;
15322                                } else {
15323                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15324                                        adj = ProcessList.VISIBLE_APP_ADJ;
15325                                    }
15326                                }
15327                                if (!client.cached) {
15328                                    app.cached = false;
15329                                }
15330                                if (client.keeping) {
15331                                    app.keeping = true;
15332                                }
15333                                adjType = "service";
15334                            }
15335                        }
15336                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15337                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15338                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15339                            }
15340                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15341                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15342                                    // Special handling of clients who are in the top state.
15343                                    // We *may* want to consider this process to be in the
15344                                    // top state as well, but only if there is not another
15345                                    // reason for it to be running.  Being on the top is a
15346                                    // special state, meaning you are specifically running
15347                                    // for the current top app.  If the process is already
15348                                    // running in the background for some other reason, it
15349                                    // is more important to continue considering it to be
15350                                    // in the background state.
15351                                    mayBeTop = true;
15352                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15353                                } else {
15354                                    // Special handling for above-top states (persistent
15355                                    // processes).  These should not bring the current process
15356                                    // into the top state, since they are not on top.  Instead
15357                                    // give them the best state after that.
15358                                    clientProcState =
15359                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15360                                }
15361                            }
15362                        } else {
15363                            if (clientProcState <
15364                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15365                                clientProcState =
15366                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15367                            }
15368                        }
15369                        if (procState > clientProcState) {
15370                            procState = clientProcState;
15371                        }
15372                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15373                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15374                            app.pendingUiClean = true;
15375                        }
15376                        if (adjType != null) {
15377                            app.adjType = adjType;
15378                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15379                                    .REASON_SERVICE_IN_USE;
15380                            app.adjSource = cr.binding.client;
15381                            app.adjSourceOom = clientAdj;
15382                            app.adjTarget = s.name;
15383                        }
15384                    }
15385                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15386                        app.treatLikeActivity = true;
15387                    }
15388                    final ActivityRecord a = cr.activity;
15389                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15390                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15391                                (a.visible || a.state == ActivityState.RESUMED
15392                                 || a.state == ActivityState.PAUSING)) {
15393                            adj = ProcessList.FOREGROUND_APP_ADJ;
15394                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15395                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15396                            }
15397                            app.cached = false;
15398                            app.adjType = "service";
15399                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15400                                    .REASON_SERVICE_IN_USE;
15401                            app.adjSource = a;
15402                            app.adjSourceOom = adj;
15403                            app.adjTarget = s.name;
15404                        }
15405                    }
15406                }
15407            }
15408        }
15409
15410        for (int provi = app.pubProviders.size()-1;
15411                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15412                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15413                        || procState > ActivityManager.PROCESS_STATE_TOP);
15414                provi--) {
15415            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15416            for (int i = cpr.connections.size()-1;
15417                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15418                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15419                            || procState > ActivityManager.PROCESS_STATE_TOP);
15420                    i--) {
15421                ContentProviderConnection conn = cpr.connections.get(i);
15422                ProcessRecord client = conn.client;
15423                if (client == app) {
15424                    // Being our own client is not interesting.
15425                    continue;
15426                }
15427                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15428                int clientProcState = client.curProcState;
15429                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15430                    // If the other app is cached for any reason, for purposes here
15431                    // we are going to consider it empty.
15432                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15433                }
15434                if (adj > clientAdj) {
15435                    if (app.hasShownUi && app != mHomeProcess
15436                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15437                        app.adjType = "cch-ui-provider";
15438                    } else {
15439                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15440                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15441                        app.adjType = "provider";
15442                    }
15443                    app.cached &= client.cached;
15444                    app.keeping |= client.keeping;
15445                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15446                            .REASON_PROVIDER_IN_USE;
15447                    app.adjSource = client;
15448                    app.adjSourceOom = clientAdj;
15449                    app.adjTarget = cpr.name;
15450                }
15451                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15452                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15453                        // Special handling of clients who are in the top state.
15454                        // We *may* want to consider this process to be in the
15455                        // top state as well, but only if there is not another
15456                        // reason for it to be running.  Being on the top is a
15457                        // special state, meaning you are specifically running
15458                        // for the current top app.  If the process is already
15459                        // running in the background for some other reason, it
15460                        // is more important to continue considering it to be
15461                        // in the background state.
15462                        mayBeTop = true;
15463                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15464                    } else {
15465                        // Special handling for above-top states (persistent
15466                        // processes).  These should not bring the current process
15467                        // into the top state, since they are not on top.  Instead
15468                        // give them the best state after that.
15469                        clientProcState =
15470                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15471                    }
15472                }
15473                if (procState > clientProcState) {
15474                    procState = clientProcState;
15475                }
15476                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15477                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15478                }
15479            }
15480            // If the provider has external (non-framework) process
15481            // dependencies, ensure that its adjustment is at least
15482            // FOREGROUND_APP_ADJ.
15483            if (cpr.hasExternalProcessHandles()) {
15484                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15485                    adj = ProcessList.FOREGROUND_APP_ADJ;
15486                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15487                    app.cached = false;
15488                    app.keeping = true;
15489                    app.adjType = "provider";
15490                    app.adjTarget = cpr.name;
15491                }
15492                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15493                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15494                }
15495            }
15496        }
15497
15498        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15499            // A client of one of our services or providers is in the top state.  We
15500            // *may* want to be in the top state, but not if we are already running in
15501            // the background for some other reason.  For the decision here, we are going
15502            // to pick out a few specific states that we want to remain in when a client
15503            // is top (states that tend to be longer-term) and otherwise allow it to go
15504            // to the top state.
15505            switch (procState) {
15506                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15507                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15508                case ActivityManager.PROCESS_STATE_SERVICE:
15509                    // These all are longer-term states, so pull them up to the top
15510                    // of the background states, but not all the way to the top state.
15511                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15512                    break;
15513                default:
15514                    // Otherwise, top is a better choice, so take it.
15515                    procState = ActivityManager.PROCESS_STATE_TOP;
15516                    break;
15517            }
15518        }
15519
15520        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15521            if (app.hasClientActivities) {
15522                // This is a cached process, but with client activities.  Mark it so.
15523                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15524                app.adjType = "cch-client-act";
15525            } else if (app.treatLikeActivity) {
15526                // This is a cached process, but somebody wants us to treat it like it has
15527                // an activity, okay!
15528                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15529                app.adjType = "cch-as-act";
15530            }
15531        }
15532
15533        if (adj == ProcessList.SERVICE_ADJ) {
15534            if (doingAll) {
15535                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15536                mNewNumServiceProcs++;
15537                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15538                if (!app.serviceb) {
15539                    // This service isn't far enough down on the LRU list to
15540                    // normally be a B service, but if we are low on RAM and it
15541                    // is large we want to force it down since we would prefer to
15542                    // keep launcher over it.
15543                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15544                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15545                        app.serviceHighRam = true;
15546                        app.serviceb = true;
15547                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15548                    } else {
15549                        mNewNumAServiceProcs++;
15550                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15551                    }
15552                } else {
15553                    app.serviceHighRam = false;
15554                }
15555            }
15556            if (app.serviceb) {
15557                adj = ProcessList.SERVICE_B_ADJ;
15558            }
15559        }
15560
15561        app.curRawAdj = adj;
15562
15563        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15564        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15565        if (adj > app.maxAdj) {
15566            adj = app.maxAdj;
15567            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15568                schedGroup = Process.THREAD_GROUP_DEFAULT;
15569            }
15570        }
15571        if (adj < ProcessList.CACHED_APP_MIN_ADJ) {
15572            app.keeping = true;
15573        }
15574
15575        // Do final modification to adj.  Everything we do between here and applying
15576        // the final setAdj must be done in this function, because we will also use
15577        // it when computing the final cached adj later.  Note that we don't need to
15578        // worry about this for max adj above, since max adj will always be used to
15579        // keep it out of the cached vaues.
15580        app.curAdj = app.modifyRawOomAdj(adj);
15581        app.curSchedGroup = schedGroup;
15582        app.curProcState = procState;
15583        app.foregroundActivities = foregroundActivities;
15584
15585        return app.curRawAdj;
15586    }
15587
15588    /**
15589     * Schedule PSS collection of a process.
15590     */
15591    void requestPssLocked(ProcessRecord proc, int procState) {
15592        if (mPendingPssProcesses.contains(proc)) {
15593            return;
15594        }
15595        if (mPendingPssProcesses.size() == 0) {
15596            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15597        }
15598        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15599        proc.pssProcState = procState;
15600        mPendingPssProcesses.add(proc);
15601    }
15602
15603    /**
15604     * Schedule PSS collection of all processes.
15605     */
15606    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15607        if (!always) {
15608            if (now < (mLastFullPssTime +
15609                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15610                return;
15611            }
15612        }
15613        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15614        mLastFullPssTime = now;
15615        mFullPssPending = true;
15616        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15617        mPendingPssProcesses.clear();
15618        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15619            ProcessRecord app = mLruProcesses.get(i);
15620            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
15621                app.pssProcState = app.setProcState;
15622                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15623                        isSleeping(), now);
15624                mPendingPssProcesses.add(app);
15625            }
15626        }
15627        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15628    }
15629
15630    /**
15631     * Ask a given process to GC right now.
15632     */
15633    final void performAppGcLocked(ProcessRecord app) {
15634        try {
15635            app.lastRequestedGc = SystemClock.uptimeMillis();
15636            if (app.thread != null) {
15637                if (app.reportLowMemory) {
15638                    app.reportLowMemory = false;
15639                    app.thread.scheduleLowMemory();
15640                } else {
15641                    app.thread.processInBackground();
15642                }
15643            }
15644        } catch (Exception e) {
15645            // whatever.
15646        }
15647    }
15648
15649    /**
15650     * Returns true if things are idle enough to perform GCs.
15651     */
15652    private final boolean canGcNowLocked() {
15653        boolean processingBroadcasts = false;
15654        for (BroadcastQueue q : mBroadcastQueues) {
15655            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
15656                processingBroadcasts = true;
15657            }
15658        }
15659        return !processingBroadcasts
15660                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
15661    }
15662
15663    /**
15664     * Perform GCs on all processes that are waiting for it, but only
15665     * if things are idle.
15666     */
15667    final void performAppGcsLocked() {
15668        final int N = mProcessesToGc.size();
15669        if (N <= 0) {
15670            return;
15671        }
15672        if (canGcNowLocked()) {
15673            while (mProcessesToGc.size() > 0) {
15674                ProcessRecord proc = mProcessesToGc.remove(0);
15675                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
15676                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
15677                            <= SystemClock.uptimeMillis()) {
15678                        // To avoid spamming the system, we will GC processes one
15679                        // at a time, waiting a few seconds between each.
15680                        performAppGcLocked(proc);
15681                        scheduleAppGcsLocked();
15682                        return;
15683                    } else {
15684                        // It hasn't been long enough since we last GCed this
15685                        // process...  put it in the list to wait for its time.
15686                        addProcessToGcListLocked(proc);
15687                        break;
15688                    }
15689                }
15690            }
15691
15692            scheduleAppGcsLocked();
15693        }
15694    }
15695
15696    /**
15697     * If all looks good, perform GCs on all processes waiting for them.
15698     */
15699    final void performAppGcsIfAppropriateLocked() {
15700        if (canGcNowLocked()) {
15701            performAppGcsLocked();
15702            return;
15703        }
15704        // Still not idle, wait some more.
15705        scheduleAppGcsLocked();
15706    }
15707
15708    /**
15709     * Schedule the execution of all pending app GCs.
15710     */
15711    final void scheduleAppGcsLocked() {
15712        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
15713
15714        if (mProcessesToGc.size() > 0) {
15715            // Schedule a GC for the time to the next process.
15716            ProcessRecord proc = mProcessesToGc.get(0);
15717            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
15718
15719            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
15720            long now = SystemClock.uptimeMillis();
15721            if (when < (now+GC_TIMEOUT)) {
15722                when = now + GC_TIMEOUT;
15723            }
15724            mHandler.sendMessageAtTime(msg, when);
15725        }
15726    }
15727
15728    /**
15729     * Add a process to the array of processes waiting to be GCed.  Keeps the
15730     * list in sorted order by the last GC time.  The process can't already be
15731     * on the list.
15732     */
15733    final void addProcessToGcListLocked(ProcessRecord proc) {
15734        boolean added = false;
15735        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
15736            if (mProcessesToGc.get(i).lastRequestedGc <
15737                    proc.lastRequestedGc) {
15738                added = true;
15739                mProcessesToGc.add(i+1, proc);
15740                break;
15741            }
15742        }
15743        if (!added) {
15744            mProcessesToGc.add(0, proc);
15745        }
15746    }
15747
15748    /**
15749     * Set up to ask a process to GC itself.  This will either do it
15750     * immediately, or put it on the list of processes to gc the next
15751     * time things are idle.
15752     */
15753    final void scheduleAppGcLocked(ProcessRecord app) {
15754        long now = SystemClock.uptimeMillis();
15755        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
15756            return;
15757        }
15758        if (!mProcessesToGc.contains(app)) {
15759            addProcessToGcListLocked(app);
15760            scheduleAppGcsLocked();
15761        }
15762    }
15763
15764    final void checkExcessivePowerUsageLocked(boolean doKills) {
15765        updateCpuStatsNow();
15766
15767        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15768        boolean doWakeKills = doKills;
15769        boolean doCpuKills = doKills;
15770        if (mLastPowerCheckRealtime == 0) {
15771            doWakeKills = false;
15772        }
15773        if (mLastPowerCheckUptime == 0) {
15774            doCpuKills = false;
15775        }
15776        if (stats.isScreenOn()) {
15777            doWakeKills = false;
15778        }
15779        final long curRealtime = SystemClock.elapsedRealtime();
15780        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
15781        final long curUptime = SystemClock.uptimeMillis();
15782        final long uptimeSince = curUptime - mLastPowerCheckUptime;
15783        mLastPowerCheckRealtime = curRealtime;
15784        mLastPowerCheckUptime = curUptime;
15785        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
15786            doWakeKills = false;
15787        }
15788        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
15789            doCpuKills = false;
15790        }
15791        int i = mLruProcesses.size();
15792        while (i > 0) {
15793            i--;
15794            ProcessRecord app = mLruProcesses.get(i);
15795            if (!app.keeping) {
15796                long wtime;
15797                synchronized (stats) {
15798                    wtime = stats.getProcessWakeTime(app.info.uid,
15799                            app.pid, curRealtime);
15800                }
15801                long wtimeUsed = wtime - app.lastWakeTime;
15802                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
15803                if (DEBUG_POWER) {
15804                    StringBuilder sb = new StringBuilder(128);
15805                    sb.append("Wake for ");
15806                    app.toShortString(sb);
15807                    sb.append(": over ");
15808                    TimeUtils.formatDuration(realtimeSince, sb);
15809                    sb.append(" used ");
15810                    TimeUtils.formatDuration(wtimeUsed, sb);
15811                    sb.append(" (");
15812                    sb.append((wtimeUsed*100)/realtimeSince);
15813                    sb.append("%)");
15814                    Slog.i(TAG, sb.toString());
15815                    sb.setLength(0);
15816                    sb.append("CPU for ");
15817                    app.toShortString(sb);
15818                    sb.append(": over ");
15819                    TimeUtils.formatDuration(uptimeSince, sb);
15820                    sb.append(" used ");
15821                    TimeUtils.formatDuration(cputimeUsed, sb);
15822                    sb.append(" (");
15823                    sb.append((cputimeUsed*100)/uptimeSince);
15824                    sb.append("%)");
15825                    Slog.i(TAG, sb.toString());
15826                }
15827                // If a process has held a wake lock for more
15828                // than 50% of the time during this period,
15829                // that sounds bad.  Kill!
15830                if (doWakeKills && realtimeSince > 0
15831                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
15832                    synchronized (stats) {
15833                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
15834                                realtimeSince, wtimeUsed);
15835                    }
15836                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
15837                            + " during " + realtimeSince);
15838                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
15839                } else if (doCpuKills && uptimeSince > 0
15840                        && ((cputimeUsed*100)/uptimeSince) >= 50) {
15841                    synchronized (stats) {
15842                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
15843                                uptimeSince, cputimeUsed);
15844                    }
15845                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
15846                            + " during " + uptimeSince);
15847                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
15848                } else {
15849                    app.lastWakeTime = wtime;
15850                    app.lastCpuTime = app.curCpuTime;
15851                }
15852            }
15853        }
15854    }
15855
15856    private final boolean applyOomAdjLocked(ProcessRecord app, boolean wasKeeping,
15857            ProcessRecord TOP_APP, boolean doingAll, long now) {
15858        boolean success = true;
15859
15860        if (app.curRawAdj != app.setRawAdj) {
15861            if (wasKeeping && !app.keeping) {
15862                // This app is no longer something we want to keep.  Note
15863                // its current wake lock time to later know to kill it if
15864                // it is not behaving well.
15865                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15866                synchronized (stats) {
15867                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
15868                            app.pid, SystemClock.elapsedRealtime());
15869                }
15870                app.lastCpuTime = app.curCpuTime;
15871            }
15872
15873            app.setRawAdj = app.curRawAdj;
15874        }
15875
15876        int changes = 0;
15877
15878        if (app.curAdj != app.setAdj) {
15879            ProcessList.setOomAdj(app.pid, app.curAdj);
15880            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
15881                TAG, "Set " + app.pid + " " + app.processName +
15882                " adj " + app.curAdj + ": " + app.adjType);
15883            app.setAdj = app.curAdj;
15884        }
15885
15886        if (app.setSchedGroup != app.curSchedGroup) {
15887            app.setSchedGroup = app.curSchedGroup;
15888            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15889                    "Setting process group of " + app.processName
15890                    + " to " + app.curSchedGroup);
15891            if (app.waitingToKill != null &&
15892                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
15893                killUnneededProcessLocked(app, app.waitingToKill);
15894                success = false;
15895            } else {
15896                if (true) {
15897                    long oldId = Binder.clearCallingIdentity();
15898                    try {
15899                        Process.setProcessGroup(app.pid, app.curSchedGroup);
15900                    } catch (Exception e) {
15901                        Slog.w(TAG, "Failed setting process group of " + app.pid
15902                                + " to " + app.curSchedGroup);
15903                        e.printStackTrace();
15904                    } finally {
15905                        Binder.restoreCallingIdentity(oldId);
15906                    }
15907                } else {
15908                    if (app.thread != null) {
15909                        try {
15910                            app.thread.setSchedulingGroup(app.curSchedGroup);
15911                        } catch (RemoteException e) {
15912                        }
15913                    }
15914                }
15915                Process.setSwappiness(app.pid,
15916                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
15917            }
15918        }
15919        if (app.repForegroundActivities != app.foregroundActivities) {
15920            app.repForegroundActivities = app.foregroundActivities;
15921            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
15922        }
15923        if (app.repProcState != app.curProcState) {
15924            app.repProcState = app.curProcState;
15925            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
15926            if (app.thread != null) {
15927                try {
15928                    if (false) {
15929                        //RuntimeException h = new RuntimeException("here");
15930                        Slog.i(TAG, "Sending new process state " + app.repProcState
15931                                + " to " + app /*, h*/);
15932                    }
15933                    app.thread.setProcessState(app.repProcState);
15934                } catch (RemoteException e) {
15935                }
15936            }
15937        }
15938        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
15939                app.setProcState)) {
15940            app.lastStateTime = now;
15941            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
15942                    isSleeping(), now);
15943            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
15944                    + ProcessList.makeProcStateString(app.setProcState) + " to "
15945                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
15946                    + (app.nextPssTime-now) + ": " + app);
15947        } else {
15948            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
15949                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
15950                requestPssLocked(app, app.setProcState);
15951                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
15952                        isSleeping(), now);
15953            } else if (false && DEBUG_PSS) {
15954                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
15955            }
15956        }
15957        if (app.setProcState != app.curProcState) {
15958            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
15959                    "Proc state change of " + app.processName
15960                    + " to " + app.curProcState);
15961            app.setProcState = app.curProcState;
15962            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
15963                app.notCachedSinceIdle = false;
15964            }
15965            if (!doingAll) {
15966                setProcessTrackerState(app, mProcessStats.getMemFactorLocked(), now);
15967            } else {
15968                app.procStateChanged = true;
15969            }
15970        }
15971
15972        if (changes != 0) {
15973            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
15974            int i = mPendingProcessChanges.size()-1;
15975            ProcessChangeItem item = null;
15976            while (i >= 0) {
15977                item = mPendingProcessChanges.get(i);
15978                if (item.pid == app.pid) {
15979                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
15980                    break;
15981                }
15982                i--;
15983            }
15984            if (i < 0) {
15985                // No existing item in pending changes; need a new one.
15986                final int NA = mAvailProcessChanges.size();
15987                if (NA > 0) {
15988                    item = mAvailProcessChanges.remove(NA-1);
15989                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
15990                } else {
15991                    item = new ProcessChangeItem();
15992                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
15993                }
15994                item.changes = 0;
15995                item.pid = app.pid;
15996                item.uid = app.info.uid;
15997                if (mPendingProcessChanges.size() == 0) {
15998                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
15999                            "*** Enqueueing dispatch processes changed!");
16000                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16001                }
16002                mPendingProcessChanges.add(item);
16003            }
16004            item.changes |= changes;
16005            item.processState = app.repProcState;
16006            item.foregroundActivities = app.repForegroundActivities;
16007            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16008                    + Integer.toHexString(System.identityHashCode(item))
16009                    + " " + app.toShortString() + ": changes=" + item.changes
16010                    + " procState=" + item.processState
16011                    + " foreground=" + item.foregroundActivities
16012                    + " type=" + app.adjType + " source=" + app.adjSource
16013                    + " target=" + app.adjTarget);
16014        }
16015
16016        return success;
16017    }
16018
16019    private final void setProcessTrackerState(ProcessRecord proc, int memFactor, long now) {
16020        if (proc.thread != null && proc.baseProcessTracker != null) {
16021            proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16022        }
16023    }
16024
16025    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16026            ProcessRecord TOP_APP, boolean doingAll, long now) {
16027        if (app.thread == null) {
16028            return false;
16029        }
16030
16031        final boolean wasKeeping = app.keeping;
16032
16033        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16034
16035        return applyOomAdjLocked(app, wasKeeping, TOP_APP, doingAll, now);
16036    }
16037
16038    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16039            boolean oomAdj) {
16040        if (isForeground != proc.foregroundServices) {
16041            proc.foregroundServices = isForeground;
16042            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16043                    proc.info.uid);
16044            if (isForeground) {
16045                if (curProcs == null) {
16046                    curProcs = new ArrayList<ProcessRecord>();
16047                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16048                }
16049                if (!curProcs.contains(proc)) {
16050                    curProcs.add(proc);
16051                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16052                            proc.info.packageName, proc.info.uid);
16053                }
16054            } else {
16055                if (curProcs != null) {
16056                    if (curProcs.remove(proc)) {
16057                        mBatteryStatsService.noteEvent(
16058                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16059                                proc.info.packageName, proc.info.uid);
16060                        if (curProcs.size() <= 0) {
16061                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16062                        }
16063                    }
16064                }
16065            }
16066            if (oomAdj) {
16067                updateOomAdjLocked();
16068            }
16069        }
16070    }
16071
16072    private final ActivityRecord resumedAppLocked() {
16073        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16074        String pkg;
16075        int uid;
16076        if (act != null && !act.sleeping) {
16077            pkg = act.packageName;
16078            uid = act.info.applicationInfo.uid;
16079        } else {
16080            pkg = null;
16081            uid = -1;
16082        }
16083        // Has the UID or resumed package name changed?
16084        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16085                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16086            if (mCurResumedPackage != null) {
16087                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16088                        mCurResumedPackage, mCurResumedUid);
16089            }
16090            mCurResumedPackage = pkg;
16091            mCurResumedUid = uid;
16092            if (mCurResumedPackage != null) {
16093                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16094                        mCurResumedPackage, mCurResumedUid);
16095            }
16096        }
16097        return act;
16098    }
16099
16100    final boolean updateOomAdjLocked(ProcessRecord app) {
16101        final ActivityRecord TOP_ACT = resumedAppLocked();
16102        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16103        final boolean wasCached = app.cached;
16104
16105        mAdjSeq++;
16106
16107        // This is the desired cached adjusment we want to tell it to use.
16108        // If our app is currently cached, we know it, and that is it.  Otherwise,
16109        // we don't know it yet, and it needs to now be cached we will then
16110        // need to do a complete oom adj.
16111        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16112                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16113        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16114                SystemClock.uptimeMillis());
16115        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16116            // Changed to/from cached state, so apps after it in the LRU
16117            // list may also be changed.
16118            updateOomAdjLocked();
16119        }
16120        return success;
16121    }
16122
16123    final void updateOomAdjLocked() {
16124        final ActivityRecord TOP_ACT = resumedAppLocked();
16125        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16126        final long now = SystemClock.uptimeMillis();
16127        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16128        final int N = mLruProcesses.size();
16129
16130        if (false) {
16131            RuntimeException e = new RuntimeException();
16132            e.fillInStackTrace();
16133            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16134        }
16135
16136        mAdjSeq++;
16137        mNewNumServiceProcs = 0;
16138        mNewNumAServiceProcs = 0;
16139
16140        final int emptyProcessLimit;
16141        final int cachedProcessLimit;
16142        if (mProcessLimit <= 0) {
16143            emptyProcessLimit = cachedProcessLimit = 0;
16144        } else if (mProcessLimit == 1) {
16145            emptyProcessLimit = 1;
16146            cachedProcessLimit = 0;
16147        } else {
16148            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16149            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16150        }
16151
16152        // Let's determine how many processes we have running vs.
16153        // how many slots we have for background processes; we may want
16154        // to put multiple processes in a slot of there are enough of
16155        // them.
16156        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16157                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16158        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16159        if (numEmptyProcs > cachedProcessLimit) {
16160            // If there are more empty processes than our limit on cached
16161            // processes, then use the cached process limit for the factor.
16162            // This ensures that the really old empty processes get pushed
16163            // down to the bottom, so if we are running low on memory we will
16164            // have a better chance at keeping around more cached processes
16165            // instead of a gazillion empty processes.
16166            numEmptyProcs = cachedProcessLimit;
16167        }
16168        int emptyFactor = numEmptyProcs/numSlots;
16169        if (emptyFactor < 1) emptyFactor = 1;
16170        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16171        if (cachedFactor < 1) cachedFactor = 1;
16172        int stepCached = 0;
16173        int stepEmpty = 0;
16174        int numCached = 0;
16175        int numEmpty = 0;
16176        int numTrimming = 0;
16177
16178        mNumNonCachedProcs = 0;
16179        mNumCachedHiddenProcs = 0;
16180
16181        // First update the OOM adjustment for each of the
16182        // application processes based on their current state.
16183        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16184        int nextCachedAdj = curCachedAdj+1;
16185        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16186        int nextEmptyAdj = curEmptyAdj+2;
16187        for (int i=N-1; i>=0; i--) {
16188            ProcessRecord app = mLruProcesses.get(i);
16189            if (!app.killedByAm && app.thread != null) {
16190                app.procStateChanged = false;
16191                final boolean wasKeeping = app.keeping;
16192                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16193
16194                // If we haven't yet assigned the final cached adj
16195                // to the process, do that now.
16196                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16197                    switch (app.curProcState) {
16198                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16199                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16200                            // This process is a cached process holding activities...
16201                            // assign it the next cached value for that type, and then
16202                            // step that cached level.
16203                            app.curRawAdj = curCachedAdj;
16204                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16205                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16206                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16207                                    + ")");
16208                            if (curCachedAdj != nextCachedAdj) {
16209                                stepCached++;
16210                                if (stepCached >= cachedFactor) {
16211                                    stepCached = 0;
16212                                    curCachedAdj = nextCachedAdj;
16213                                    nextCachedAdj += 2;
16214                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16215                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16216                                    }
16217                                }
16218                            }
16219                            break;
16220                        default:
16221                            // For everything else, assign next empty cached process
16222                            // level and bump that up.  Note that this means that
16223                            // long-running services that have dropped down to the
16224                            // cached level will be treated as empty (since their process
16225                            // state is still as a service), which is what we want.
16226                            app.curRawAdj = curEmptyAdj;
16227                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16228                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16229                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16230                                    + ")");
16231                            if (curEmptyAdj != nextEmptyAdj) {
16232                                stepEmpty++;
16233                                if (stepEmpty >= emptyFactor) {
16234                                    stepEmpty = 0;
16235                                    curEmptyAdj = nextEmptyAdj;
16236                                    nextEmptyAdj += 2;
16237                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16238                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16239                                    }
16240                                }
16241                            }
16242                            break;
16243                    }
16244                }
16245
16246                applyOomAdjLocked(app, wasKeeping, TOP_APP, true, now);
16247
16248                // Count the number of process types.
16249                switch (app.curProcState) {
16250                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16251                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16252                        mNumCachedHiddenProcs++;
16253                        numCached++;
16254                        if (numCached > cachedProcessLimit) {
16255                            killUnneededProcessLocked(app, "cached #" + numCached);
16256                        }
16257                        break;
16258                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16259                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16260                                && app.lastActivityTime < oldTime) {
16261                            killUnneededProcessLocked(app, "empty for "
16262                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16263                                    / 1000) + "s");
16264                        } else {
16265                            numEmpty++;
16266                            if (numEmpty > emptyProcessLimit) {
16267                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16268                            }
16269                        }
16270                        break;
16271                    default:
16272                        mNumNonCachedProcs++;
16273                        break;
16274                }
16275
16276                if (app.isolated && app.services.size() <= 0) {
16277                    // If this is an isolated process, and there are no
16278                    // services running in it, then the process is no longer
16279                    // needed.  We agressively kill these because we can by
16280                    // definition not re-use the same process again, and it is
16281                    // good to avoid having whatever code was running in them
16282                    // left sitting around after no longer needed.
16283                    killUnneededProcessLocked(app, "isolated not needed");
16284                }
16285
16286                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16287                        && !app.killedByAm) {
16288                    numTrimming++;
16289                }
16290            }
16291        }
16292
16293        mNumServiceProcs = mNewNumServiceProcs;
16294
16295        // Now determine the memory trimming level of background processes.
16296        // Unfortunately we need to start at the back of the list to do this
16297        // properly.  We only do this if the number of background apps we
16298        // are managing to keep around is less than half the maximum we desire;
16299        // if we are keeping a good number around, we'll let them use whatever
16300        // memory they want.
16301        final int numCachedAndEmpty = numCached + numEmpty;
16302        int memFactor;
16303        if (numCached <= ProcessList.TRIM_CACHED_APPS
16304                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16305            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16306                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16307            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16308                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16309            } else {
16310                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16311            }
16312        } else {
16313            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16314        }
16315        // We always allow the memory level to go up (better).  We only allow it to go
16316        // down if we are in a state where that is allowed, *and* the total number of processes
16317        // has gone down since last time.
16318        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16319                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16320                + " last=" + mLastNumProcesses);
16321        if (memFactor > mLastMemoryLevel) {
16322            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16323                memFactor = mLastMemoryLevel;
16324                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16325            }
16326        }
16327        mLastMemoryLevel = memFactor;
16328        mLastNumProcesses = mLruProcesses.size();
16329        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16330        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16331        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16332            if (mLowRamStartTime == 0) {
16333                mLowRamStartTime = now;
16334            }
16335            int step = 0;
16336            int fgTrimLevel;
16337            switch (memFactor) {
16338                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16339                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16340                    break;
16341                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16342                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16343                    break;
16344                default:
16345                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16346                    break;
16347            }
16348            int factor = numTrimming/3;
16349            int minFactor = 2;
16350            if (mHomeProcess != null) minFactor++;
16351            if (mPreviousProcess != null) minFactor++;
16352            if (factor < minFactor) factor = minFactor;
16353            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16354            for (int i=N-1; i>=0; i--) {
16355                ProcessRecord app = mLruProcesses.get(i);
16356                if (allChanged || app.procStateChanged) {
16357                    setProcessTrackerState(app, trackerMemFactor, now);
16358                    app.procStateChanged = false;
16359                }
16360                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16361                        && !app.killedByAm) {
16362                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16363                        try {
16364                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16365                                    "Trimming memory of " + app.processName
16366                                    + " to " + curLevel);
16367                            app.thread.scheduleTrimMemory(curLevel);
16368                        } catch (RemoteException e) {
16369                        }
16370                        if (false) {
16371                            // For now we won't do this; our memory trimming seems
16372                            // to be good enough at this point that destroying
16373                            // activities causes more harm than good.
16374                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16375                                    && app != mHomeProcess && app != mPreviousProcess) {
16376                                // Need to do this on its own message because the stack may not
16377                                // be in a consistent state at this point.
16378                                // For these apps we will also finish their activities
16379                                // to help them free memory.
16380                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16381                            }
16382                        }
16383                    }
16384                    app.trimMemoryLevel = curLevel;
16385                    step++;
16386                    if (step >= factor) {
16387                        step = 0;
16388                        switch (curLevel) {
16389                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16390                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16391                                break;
16392                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16393                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16394                                break;
16395                        }
16396                    }
16397                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16398                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16399                            && app.thread != null) {
16400                        try {
16401                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16402                                    "Trimming memory of heavy-weight " + app.processName
16403                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16404                            app.thread.scheduleTrimMemory(
16405                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16406                        } catch (RemoteException e) {
16407                        }
16408                    }
16409                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16410                } else {
16411                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16412                            || app.systemNoUi) && app.pendingUiClean) {
16413                        // If this application is now in the background and it
16414                        // had done UI, then give it the special trim level to
16415                        // have it free UI resources.
16416                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16417                        if (app.trimMemoryLevel < level && app.thread != null) {
16418                            try {
16419                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16420                                        "Trimming memory of bg-ui " + app.processName
16421                                        + " to " + level);
16422                                app.thread.scheduleTrimMemory(level);
16423                            } catch (RemoteException e) {
16424                            }
16425                        }
16426                        app.pendingUiClean = false;
16427                    }
16428                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16429                        try {
16430                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16431                                    "Trimming memory of fg " + app.processName
16432                                    + " to " + fgTrimLevel);
16433                            app.thread.scheduleTrimMemory(fgTrimLevel);
16434                        } catch (RemoteException e) {
16435                        }
16436                    }
16437                    app.trimMemoryLevel = fgTrimLevel;
16438                }
16439            }
16440        } else {
16441            if (mLowRamStartTime != 0) {
16442                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16443                mLowRamStartTime = 0;
16444            }
16445            for (int i=N-1; i>=0; i--) {
16446                ProcessRecord app = mLruProcesses.get(i);
16447                if (allChanged || app.procStateChanged) {
16448                    setProcessTrackerState(app, trackerMemFactor, now);
16449                    app.procStateChanged = false;
16450                }
16451                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16452                        || app.systemNoUi) && app.pendingUiClean) {
16453                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16454                            && app.thread != null) {
16455                        try {
16456                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16457                                    "Trimming memory of ui hidden " + app.processName
16458                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16459                            app.thread.scheduleTrimMemory(
16460                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16461                        } catch (RemoteException e) {
16462                        }
16463                    }
16464                    app.pendingUiClean = false;
16465                }
16466                app.trimMemoryLevel = 0;
16467            }
16468        }
16469
16470        if (mAlwaysFinishActivities) {
16471            // Need to do this on its own message because the stack may not
16472            // be in a consistent state at this point.
16473            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16474        }
16475
16476        if (allChanged) {
16477            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16478        }
16479
16480        if (mProcessStats.shouldWriteNowLocked(now)) {
16481            mHandler.post(new Runnable() {
16482                @Override public void run() {
16483                    synchronized (ActivityManagerService.this) {
16484                        mProcessStats.writeStateAsyncLocked();
16485                    }
16486                }
16487            });
16488        }
16489
16490        if (DEBUG_OOM_ADJ) {
16491            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16492        }
16493    }
16494
16495    final void trimApplications() {
16496        synchronized (this) {
16497            int i;
16498
16499            // First remove any unused application processes whose package
16500            // has been removed.
16501            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16502                final ProcessRecord app = mRemovedProcesses.get(i);
16503                if (app.activities.size() == 0
16504                        && app.curReceiver == null && app.services.size() == 0) {
16505                    Slog.i(
16506                        TAG, "Exiting empty application process "
16507                        + app.processName + " ("
16508                        + (app.thread != null ? app.thread.asBinder() : null)
16509                        + ")\n");
16510                    if (app.pid > 0 && app.pid != MY_PID) {
16511                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16512                                app.processName, app.setAdj, "empty");
16513                        app.killedByAm = true;
16514                        Process.killProcessQuiet(app.pid);
16515                    } else {
16516                        try {
16517                            app.thread.scheduleExit();
16518                        } catch (Exception e) {
16519                            // Ignore exceptions.
16520                        }
16521                    }
16522                    cleanUpApplicationRecordLocked(app, false, true, -1);
16523                    mRemovedProcesses.remove(i);
16524
16525                    if (app.persistent) {
16526                        if (app.persistent) {
16527                            addAppLocked(app.info, false, null /* ABI override */);
16528                        }
16529                    }
16530                }
16531            }
16532
16533            // Now update the oom adj for all processes.
16534            updateOomAdjLocked();
16535        }
16536    }
16537
16538    /** This method sends the specified signal to each of the persistent apps */
16539    public void signalPersistentProcesses(int sig) throws RemoteException {
16540        if (sig != Process.SIGNAL_USR1) {
16541            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16542        }
16543
16544        synchronized (this) {
16545            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16546                    != PackageManager.PERMISSION_GRANTED) {
16547                throw new SecurityException("Requires permission "
16548                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16549            }
16550
16551            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16552                ProcessRecord r = mLruProcesses.get(i);
16553                if (r.thread != null && r.persistent) {
16554                    Process.sendSignal(r.pid, sig);
16555                }
16556            }
16557        }
16558    }
16559
16560    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16561        if (proc == null || proc == mProfileProc) {
16562            proc = mProfileProc;
16563            path = mProfileFile;
16564            profileType = mProfileType;
16565            clearProfilerLocked();
16566        }
16567        if (proc == null) {
16568            return;
16569        }
16570        try {
16571            proc.thread.profilerControl(false, path, null, profileType);
16572        } catch (RemoteException e) {
16573            throw new IllegalStateException("Process disappeared");
16574        }
16575    }
16576
16577    private void clearProfilerLocked() {
16578        if (mProfileFd != null) {
16579            try {
16580                mProfileFd.close();
16581            } catch (IOException e) {
16582            }
16583        }
16584        mProfileApp = null;
16585        mProfileProc = null;
16586        mProfileFile = null;
16587        mProfileType = 0;
16588        mAutoStopProfiler = false;
16589    }
16590
16591    public boolean profileControl(String process, int userId, boolean start,
16592            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16593
16594        try {
16595            synchronized (this) {
16596                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16597                // its own permission.
16598                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16599                        != PackageManager.PERMISSION_GRANTED) {
16600                    throw new SecurityException("Requires permission "
16601                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16602                }
16603
16604                if (start && fd == null) {
16605                    throw new IllegalArgumentException("null fd");
16606                }
16607
16608                ProcessRecord proc = null;
16609                if (process != null) {
16610                    proc = findProcessLocked(process, userId, "profileControl");
16611                }
16612
16613                if (start && (proc == null || proc.thread == null)) {
16614                    throw new IllegalArgumentException("Unknown process: " + process);
16615                }
16616
16617                if (start) {
16618                    stopProfilerLocked(null, null, 0);
16619                    setProfileApp(proc.info, proc.processName, path, fd, false);
16620                    mProfileProc = proc;
16621                    mProfileType = profileType;
16622                    try {
16623                        fd = fd.dup();
16624                    } catch (IOException e) {
16625                        fd = null;
16626                    }
16627                    proc.thread.profilerControl(start, path, fd, profileType);
16628                    fd = null;
16629                    mProfileFd = null;
16630                } else {
16631                    stopProfilerLocked(proc, path, profileType);
16632                    if (fd != null) {
16633                        try {
16634                            fd.close();
16635                        } catch (IOException e) {
16636                        }
16637                    }
16638                }
16639
16640                return true;
16641            }
16642        } catch (RemoteException e) {
16643            throw new IllegalStateException("Process disappeared");
16644        } finally {
16645            if (fd != null) {
16646                try {
16647                    fd.close();
16648                } catch (IOException e) {
16649                }
16650            }
16651        }
16652    }
16653
16654    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
16655        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
16656                userId, true, true, callName, null);
16657        ProcessRecord proc = null;
16658        try {
16659            int pid = Integer.parseInt(process);
16660            synchronized (mPidsSelfLocked) {
16661                proc = mPidsSelfLocked.get(pid);
16662            }
16663        } catch (NumberFormatException e) {
16664        }
16665
16666        if (proc == null) {
16667            ArrayMap<String, SparseArray<ProcessRecord>> all
16668                    = mProcessNames.getMap();
16669            SparseArray<ProcessRecord> procs = all.get(process);
16670            if (procs != null && procs.size() > 0) {
16671                proc = procs.valueAt(0);
16672                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
16673                    for (int i=1; i<procs.size(); i++) {
16674                        ProcessRecord thisProc = procs.valueAt(i);
16675                        if (thisProc.userId == userId) {
16676                            proc = thisProc;
16677                            break;
16678                        }
16679                    }
16680                }
16681            }
16682        }
16683
16684        return proc;
16685    }
16686
16687    public boolean dumpHeap(String process, int userId, boolean managed,
16688            String path, ParcelFileDescriptor fd) throws RemoteException {
16689
16690        try {
16691            synchronized (this) {
16692                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16693                // its own permission (same as profileControl).
16694                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16695                        != PackageManager.PERMISSION_GRANTED) {
16696                    throw new SecurityException("Requires permission "
16697                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16698                }
16699
16700                if (fd == null) {
16701                    throw new IllegalArgumentException("null fd");
16702                }
16703
16704                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
16705                if (proc == null || proc.thread == null) {
16706                    throw new IllegalArgumentException("Unknown process: " + process);
16707                }
16708
16709                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
16710                if (!isDebuggable) {
16711                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
16712                        throw new SecurityException("Process not debuggable: " + proc);
16713                    }
16714                }
16715
16716                proc.thread.dumpHeap(managed, path, fd);
16717                fd = null;
16718                return true;
16719            }
16720        } catch (RemoteException e) {
16721            throw new IllegalStateException("Process disappeared");
16722        } finally {
16723            if (fd != null) {
16724                try {
16725                    fd.close();
16726                } catch (IOException e) {
16727                }
16728            }
16729        }
16730    }
16731
16732    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
16733    public void monitor() {
16734        synchronized (this) { }
16735    }
16736
16737    void onCoreSettingsChange(Bundle settings) {
16738        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
16739            ProcessRecord processRecord = mLruProcesses.get(i);
16740            try {
16741                if (processRecord.thread != null) {
16742                    processRecord.thread.setCoreSettings(settings);
16743                }
16744            } catch (RemoteException re) {
16745                /* ignore */
16746            }
16747        }
16748    }
16749
16750    // Multi-user methods
16751
16752    /**
16753     * Start user, if its not already running, but don't bring it to foreground.
16754     */
16755    @Override
16756    public boolean startUserInBackground(final int userId) {
16757        return startUser(userId, /* foreground */ false);
16758    }
16759
16760    /**
16761     * Refreshes the list of users related to the current user when either a
16762     * user switch happens or when a new related user is started in the
16763     * background.
16764     */
16765    private void updateCurrentProfileIdsLocked() {
16766        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16767                mCurrentUserId, false /* enabledOnly */);
16768        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
16769        for (int i = 0; i < currentProfileIds.length; i++) {
16770            currentProfileIds[i] = profiles.get(i).id;
16771        }
16772        mCurrentProfileIds = currentProfileIds;
16773    }
16774
16775    private Set getProfileIdsLocked(int userId) {
16776        Set userIds = new HashSet<Integer>();
16777        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
16778                userId, false /* enabledOnly */);
16779        for (UserInfo user : profiles) {
16780            userIds.add(Integer.valueOf(user.id));
16781        }
16782        return userIds;
16783    }
16784
16785    @Override
16786    public boolean switchUser(final int userId) {
16787        return startUser(userId, /* foregound */ true);
16788    }
16789
16790    private boolean startUser(final int userId, boolean foreground) {
16791        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
16792                != PackageManager.PERMISSION_GRANTED) {
16793            String msg = "Permission Denial: switchUser() from pid="
16794                    + Binder.getCallingPid()
16795                    + ", uid=" + Binder.getCallingUid()
16796                    + " requires " + INTERACT_ACROSS_USERS_FULL;
16797            Slog.w(TAG, msg);
16798            throw new SecurityException(msg);
16799        }
16800
16801        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
16802
16803        final long ident = Binder.clearCallingIdentity();
16804        try {
16805            synchronized (this) {
16806                final int oldUserId = mCurrentUserId;
16807                if (oldUserId == userId) {
16808                    return true;
16809                }
16810
16811                mStackSupervisor.setLockTaskModeLocked(null, false);
16812
16813                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
16814                if (userInfo == null) {
16815                    Slog.w(TAG, "No user info for user #" + userId);
16816                    return false;
16817                }
16818
16819                if (foreground) {
16820                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
16821                            R.anim.screen_user_enter);
16822                }
16823
16824                boolean needStart = false;
16825
16826                // If the user we are switching to is not currently started, then
16827                // we need to start it now.
16828                if (mStartedUsers.get(userId) == null) {
16829                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
16830                    updateStartedUserArrayLocked();
16831                    needStart = true;
16832                }
16833
16834                final Integer userIdInt = Integer.valueOf(userId);
16835                mUserLru.remove(userIdInt);
16836                mUserLru.add(userIdInt);
16837
16838                if (foreground) {
16839                    mCurrentUserId = userId;
16840                    updateCurrentProfileIdsLocked();
16841                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
16842                    // Once the internal notion of the active user has switched, we lock the device
16843                    // with the option to show the user switcher on the keyguard.
16844                    mWindowManager.lockNow(null);
16845                } else {
16846                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
16847                    updateCurrentProfileIdsLocked();
16848                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
16849                    mUserLru.remove(currentUserIdInt);
16850                    mUserLru.add(currentUserIdInt);
16851                }
16852
16853                final UserStartedState uss = mStartedUsers.get(userId);
16854
16855                // Make sure user is in the started state.  If it is currently
16856                // stopping, we need to knock that off.
16857                if (uss.mState == UserStartedState.STATE_STOPPING) {
16858                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
16859                    // so we can just fairly silently bring the user back from
16860                    // the almost-dead.
16861                    uss.mState = UserStartedState.STATE_RUNNING;
16862                    updateStartedUserArrayLocked();
16863                    needStart = true;
16864                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
16865                    // This means ACTION_SHUTDOWN has been sent, so we will
16866                    // need to treat this as a new boot of the user.
16867                    uss.mState = UserStartedState.STATE_BOOTING;
16868                    updateStartedUserArrayLocked();
16869                    needStart = true;
16870                }
16871
16872                if (uss.mState == UserStartedState.STATE_BOOTING) {
16873                    // Booting up a new user, need to tell system services about it.
16874                    // Note that this is on the same handler as scheduling of broadcasts,
16875                    // which is important because it needs to go first.
16876                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
16877                }
16878
16879                if (foreground) {
16880                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId));
16881                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
16882                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
16883                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
16884                            oldUserId, userId, uss));
16885                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
16886                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
16887                }
16888
16889                if (needStart) {
16890                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
16891                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16892                            | Intent.FLAG_RECEIVER_FOREGROUND);
16893                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16894                    broadcastIntentLocked(null, null, intent,
16895                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16896                            false, false, MY_PID, Process.SYSTEM_UID, userId);
16897                }
16898
16899                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
16900                    if (userId != UserHandle.USER_OWNER) {
16901                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
16902                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
16903                        broadcastIntentLocked(null, null, intent, null,
16904                                new IIntentReceiver.Stub() {
16905                                    public void performReceive(Intent intent, int resultCode,
16906                                            String data, Bundle extras, boolean ordered,
16907                                            boolean sticky, int sendingUser) {
16908                                        userInitialized(uss, userId);
16909                                    }
16910                                }, 0, null, null, null, AppOpsManager.OP_NONE,
16911                                true, false, MY_PID, Process.SYSTEM_UID,
16912                                userId);
16913                        uss.initializing = true;
16914                    } else {
16915                        getUserManagerLocked().makeInitialized(userInfo.id);
16916                    }
16917                }
16918
16919                if (foreground) {
16920                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
16921                    if (homeInFront) {
16922                        startHomeActivityLocked(userId);
16923                    } else {
16924                        mStackSupervisor.resumeTopActivitiesLocked();
16925                    }
16926                    EventLogTags.writeAmSwitchUser(userId);
16927                    getUserManagerLocked().userForeground(userId);
16928                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
16929                } else {
16930                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
16931                }
16932
16933                if (needStart) {
16934                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
16935                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
16936                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
16937                    broadcastIntentLocked(null, null, intent,
16938                            null, new IIntentReceiver.Stub() {
16939                                @Override
16940                                public void performReceive(Intent intent, int resultCode, String data,
16941                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
16942                                        throws RemoteException {
16943                                }
16944                            }, 0, null, null,
16945                            android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
16946                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16947                }
16948            }
16949        } finally {
16950            Binder.restoreCallingIdentity(ident);
16951        }
16952
16953        return true;
16954    }
16955
16956    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
16957        long ident = Binder.clearCallingIdentity();
16958        try {
16959            Intent intent;
16960            if (oldUserId >= 0) {
16961                intent = new Intent(Intent.ACTION_USER_BACKGROUND);
16962                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16963                        | Intent.FLAG_RECEIVER_FOREGROUND);
16964                intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
16965                broadcastIntentLocked(null, null, intent,
16966                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16967                        false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
16968            }
16969            if (newUserId >= 0) {
16970                intent = new Intent(Intent.ACTION_USER_FOREGROUND);
16971                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16972                        | Intent.FLAG_RECEIVER_FOREGROUND);
16973                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16974                broadcastIntentLocked(null, null, intent,
16975                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
16976                        false, false, MY_PID, Process.SYSTEM_UID, newUserId);
16977                intent = new Intent(Intent.ACTION_USER_SWITCHED);
16978                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
16979                        | Intent.FLAG_RECEIVER_FOREGROUND);
16980                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
16981                broadcastIntentLocked(null, null, intent,
16982                        null, null, 0, null, null,
16983                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
16984                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
16985            }
16986        } finally {
16987            Binder.restoreCallingIdentity(ident);
16988        }
16989    }
16990
16991    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
16992            final int newUserId) {
16993        final int N = mUserSwitchObservers.beginBroadcast();
16994        if (N > 0) {
16995            final IRemoteCallback callback = new IRemoteCallback.Stub() {
16996                int mCount = 0;
16997                @Override
16998                public void sendResult(Bundle data) throws RemoteException {
16999                    synchronized (ActivityManagerService.this) {
17000                        if (mCurUserSwitchCallback == this) {
17001                            mCount++;
17002                            if (mCount == N) {
17003                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17004                            }
17005                        }
17006                    }
17007                }
17008            };
17009            synchronized (this) {
17010                uss.switching = true;
17011                mCurUserSwitchCallback = callback;
17012            }
17013            for (int i=0; i<N; i++) {
17014                try {
17015                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17016                            newUserId, callback);
17017                } catch (RemoteException e) {
17018                }
17019            }
17020        } else {
17021            synchronized (this) {
17022                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17023            }
17024        }
17025        mUserSwitchObservers.finishBroadcast();
17026    }
17027
17028    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17029        synchronized (this) {
17030            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17031            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17032        }
17033    }
17034
17035    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17036        mCurUserSwitchCallback = null;
17037        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17038        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17039                oldUserId, newUserId, uss));
17040    }
17041
17042    void userInitialized(UserStartedState uss, int newUserId) {
17043        completeSwitchAndInitalize(uss, newUserId, true, false);
17044    }
17045
17046    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17047        completeSwitchAndInitalize(uss, newUserId, false, true);
17048    }
17049
17050    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17051            boolean clearInitializing, boolean clearSwitching) {
17052        boolean unfrozen = false;
17053        synchronized (this) {
17054            if (clearInitializing) {
17055                uss.initializing = false;
17056                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17057            }
17058            if (clearSwitching) {
17059                uss.switching = false;
17060            }
17061            if (!uss.switching && !uss.initializing) {
17062                mWindowManager.stopFreezingScreen();
17063                unfrozen = true;
17064            }
17065        }
17066        if (unfrozen) {
17067            final int N = mUserSwitchObservers.beginBroadcast();
17068            for (int i=0; i<N; i++) {
17069                try {
17070                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17071                } catch (RemoteException e) {
17072                }
17073            }
17074            mUserSwitchObservers.finishBroadcast();
17075        }
17076    }
17077
17078    void scheduleStartProfilesLocked() {
17079        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17080            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17081                    DateUtils.SECOND_IN_MILLIS);
17082        }
17083    }
17084
17085    void startProfilesLocked() {
17086        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17087        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17088                mCurrentUserId, false /* enabledOnly */);
17089        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17090        for (UserInfo user : profiles) {
17091            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17092                    && user.id != mCurrentUserId) {
17093                toStart.add(user);
17094            }
17095        }
17096        final int n = toStart.size();
17097        int i = 0;
17098        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17099            startUserInBackground(toStart.get(i).id);
17100        }
17101        if (i < n) {
17102            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17103        }
17104    }
17105
17106    void finishUserBoot(UserStartedState uss) {
17107        synchronized (this) {
17108            if (uss.mState == UserStartedState.STATE_BOOTING
17109                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17110                uss.mState = UserStartedState.STATE_RUNNING;
17111                final int userId = uss.mHandle.getIdentifier();
17112                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17113                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17114                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17115                broadcastIntentLocked(null, null, intent,
17116                        null, null, 0, null, null,
17117                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17118                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17119            }
17120        }
17121    }
17122
17123    void finishUserSwitch(UserStartedState uss) {
17124        synchronized (this) {
17125            finishUserBoot(uss);
17126
17127            startProfilesLocked();
17128
17129            int num = mUserLru.size();
17130            int i = 0;
17131            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17132                Integer oldUserId = mUserLru.get(i);
17133                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17134                if (oldUss == null) {
17135                    // Shouldn't happen, but be sane if it does.
17136                    mUserLru.remove(i);
17137                    num--;
17138                    continue;
17139                }
17140                if (oldUss.mState == UserStartedState.STATE_STOPPING
17141                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17142                    // This user is already stopping, doesn't count.
17143                    num--;
17144                    i++;
17145                    continue;
17146                }
17147                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17148                    // Owner and current can't be stopped, but count as running.
17149                    i++;
17150                    continue;
17151                }
17152                // This is a user to be stopped.
17153                stopUserLocked(oldUserId, null);
17154                num--;
17155                i++;
17156            }
17157        }
17158    }
17159
17160    @Override
17161    public int stopUser(final int userId, final IStopUserCallback callback) {
17162        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17163                != PackageManager.PERMISSION_GRANTED) {
17164            String msg = "Permission Denial: switchUser() from pid="
17165                    + Binder.getCallingPid()
17166                    + ", uid=" + Binder.getCallingUid()
17167                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17168            Slog.w(TAG, msg);
17169            throw new SecurityException(msg);
17170        }
17171        if (userId <= 0) {
17172            throw new IllegalArgumentException("Can't stop primary user " + userId);
17173        }
17174        synchronized (this) {
17175            return stopUserLocked(userId, callback);
17176        }
17177    }
17178
17179    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17180        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17181        if (mCurrentUserId == userId) {
17182            return ActivityManager.USER_OP_IS_CURRENT;
17183        }
17184
17185        final UserStartedState uss = mStartedUsers.get(userId);
17186        if (uss == null) {
17187            // User is not started, nothing to do...  but we do need to
17188            // callback if requested.
17189            if (callback != null) {
17190                mHandler.post(new Runnable() {
17191                    @Override
17192                    public void run() {
17193                        try {
17194                            callback.userStopped(userId);
17195                        } catch (RemoteException e) {
17196                        }
17197                    }
17198                });
17199            }
17200            return ActivityManager.USER_OP_SUCCESS;
17201        }
17202
17203        if (callback != null) {
17204            uss.mStopCallbacks.add(callback);
17205        }
17206
17207        if (uss.mState != UserStartedState.STATE_STOPPING
17208                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17209            uss.mState = UserStartedState.STATE_STOPPING;
17210            updateStartedUserArrayLocked();
17211
17212            long ident = Binder.clearCallingIdentity();
17213            try {
17214                // We are going to broadcast ACTION_USER_STOPPING and then
17215                // once that is done send a final ACTION_SHUTDOWN and then
17216                // stop the user.
17217                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17218                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17219                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17220                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17221                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17222                // This is the result receiver for the final shutdown broadcast.
17223                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17224                    @Override
17225                    public void performReceive(Intent intent, int resultCode, String data,
17226                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17227                        finishUserStop(uss);
17228                    }
17229                };
17230                // This is the result receiver for the initial stopping broadcast.
17231                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17232                    @Override
17233                    public void performReceive(Intent intent, int resultCode, String data,
17234                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17235                        // On to the next.
17236                        synchronized (ActivityManagerService.this) {
17237                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17238                                // Whoops, we are being started back up.  Abort, abort!
17239                                return;
17240                            }
17241                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17242                        }
17243                        mSystemServiceManager.stopUser(userId);
17244                        broadcastIntentLocked(null, null, shutdownIntent,
17245                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17246                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17247                    }
17248                };
17249                // Kick things off.
17250                broadcastIntentLocked(null, null, stoppingIntent,
17251                        null, stoppingReceiver, 0, null, null,
17252                        android.Manifest.permission.INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17253                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17254            } finally {
17255                Binder.restoreCallingIdentity(ident);
17256            }
17257        }
17258
17259        return ActivityManager.USER_OP_SUCCESS;
17260    }
17261
17262    void finishUserStop(UserStartedState uss) {
17263        final int userId = uss.mHandle.getIdentifier();
17264        boolean stopped;
17265        ArrayList<IStopUserCallback> callbacks;
17266        synchronized (this) {
17267            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17268            if (mStartedUsers.get(userId) != uss) {
17269                stopped = false;
17270            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17271                stopped = false;
17272            } else {
17273                stopped = true;
17274                // User can no longer run.
17275                mStartedUsers.remove(userId);
17276                mUserLru.remove(Integer.valueOf(userId));
17277                updateStartedUserArrayLocked();
17278
17279                // Clean up all state and processes associated with the user.
17280                // Kill all the processes for the user.
17281                forceStopUserLocked(userId, "finish user");
17282            }
17283        }
17284
17285        for (int i=0; i<callbacks.size(); i++) {
17286            try {
17287                if (stopped) callbacks.get(i).userStopped(userId);
17288                else callbacks.get(i).userStopAborted(userId);
17289            } catch (RemoteException e) {
17290            }
17291        }
17292
17293        if (stopped) {
17294            mSystemServiceManager.cleanupUser(userId);
17295            synchronized (this) {
17296                mStackSupervisor.removeUserLocked(userId);
17297            }
17298        }
17299    }
17300
17301    @Override
17302    public UserInfo getCurrentUser() {
17303        if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17304                != PackageManager.PERMISSION_GRANTED) && (
17305                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17306                != PackageManager.PERMISSION_GRANTED)) {
17307            String msg = "Permission Denial: getCurrentUser() from pid="
17308                    + Binder.getCallingPid()
17309                    + ", uid=" + Binder.getCallingUid()
17310                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17311            Slog.w(TAG, msg);
17312            throw new SecurityException(msg);
17313        }
17314        synchronized (this) {
17315            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17316        }
17317    }
17318
17319    int getCurrentUserIdLocked() {
17320        return mCurrentUserId;
17321    }
17322
17323    @Override
17324    public boolean isUserRunning(int userId, boolean orStopped) {
17325        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17326                != PackageManager.PERMISSION_GRANTED) {
17327            String msg = "Permission Denial: isUserRunning() from pid="
17328                    + Binder.getCallingPid()
17329                    + ", uid=" + Binder.getCallingUid()
17330                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17331            Slog.w(TAG, msg);
17332            throw new SecurityException(msg);
17333        }
17334        synchronized (this) {
17335            return isUserRunningLocked(userId, orStopped);
17336        }
17337    }
17338
17339    boolean isUserRunningLocked(int userId, boolean orStopped) {
17340        UserStartedState state = mStartedUsers.get(userId);
17341        if (state == null) {
17342            return false;
17343        }
17344        if (orStopped) {
17345            return true;
17346        }
17347        return state.mState != UserStartedState.STATE_STOPPING
17348                && state.mState != UserStartedState.STATE_SHUTDOWN;
17349    }
17350
17351    @Override
17352    public int[] getRunningUserIds() {
17353        if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
17354                != PackageManager.PERMISSION_GRANTED) {
17355            String msg = "Permission Denial: isUserRunning() from pid="
17356                    + Binder.getCallingPid()
17357                    + ", uid=" + Binder.getCallingUid()
17358                    + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
17359            Slog.w(TAG, msg);
17360            throw new SecurityException(msg);
17361        }
17362        synchronized (this) {
17363            return mStartedUserArray;
17364        }
17365    }
17366
17367    private void updateStartedUserArrayLocked() {
17368        int num = 0;
17369        for (int i=0; i<mStartedUsers.size();  i++) {
17370            UserStartedState uss = mStartedUsers.valueAt(i);
17371            // This list does not include stopping users.
17372            if (uss.mState != UserStartedState.STATE_STOPPING
17373                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17374                num++;
17375            }
17376        }
17377        mStartedUserArray = new int[num];
17378        num = 0;
17379        for (int i=0; i<mStartedUsers.size();  i++) {
17380            UserStartedState uss = mStartedUsers.valueAt(i);
17381            if (uss.mState != UserStartedState.STATE_STOPPING
17382                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17383                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17384                num++;
17385            }
17386        }
17387    }
17388
17389    @Override
17390    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17391        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17392                != PackageManager.PERMISSION_GRANTED) {
17393            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17394                    + Binder.getCallingPid()
17395                    + ", uid=" + Binder.getCallingUid()
17396                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17397            Slog.w(TAG, msg);
17398            throw new SecurityException(msg);
17399        }
17400
17401        mUserSwitchObservers.register(observer);
17402    }
17403
17404    @Override
17405    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17406        mUserSwitchObservers.unregister(observer);
17407    }
17408
17409    private boolean userExists(int userId) {
17410        if (userId == 0) {
17411            return true;
17412        }
17413        UserManagerService ums = getUserManagerLocked();
17414        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17415    }
17416
17417    int[] getUsersLocked() {
17418        UserManagerService ums = getUserManagerLocked();
17419        return ums != null ? ums.getUserIds() : new int[] { 0 };
17420    }
17421
17422    UserManagerService getUserManagerLocked() {
17423        if (mUserManager == null) {
17424            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17425            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17426        }
17427        return mUserManager;
17428    }
17429
17430    private int applyUserId(int uid, int userId) {
17431        return UserHandle.getUid(userId, uid);
17432    }
17433
17434    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17435        if (info == null) return null;
17436        ApplicationInfo newInfo = new ApplicationInfo(info);
17437        newInfo.uid = applyUserId(info.uid, userId);
17438        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17439                + info.packageName;
17440        return newInfo;
17441    }
17442
17443    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17444        if (aInfo == null
17445                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17446            return aInfo;
17447        }
17448
17449        ActivityInfo info = new ActivityInfo(aInfo);
17450        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17451        return info;
17452    }
17453
17454    private final class LocalService extends ActivityManagerInternal {
17455        @Override
17456        public void goingToSleep() {
17457            ActivityManagerService.this.goingToSleep();
17458        }
17459
17460        @Override
17461        public void wakingUp() {
17462            ActivityManagerService.this.wakingUp();
17463        }
17464    }
17465
17466    /**
17467     * An implementation of IAppTask, that allows an app to manage its own tasks via
17468     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17469     * only the process that calls getAppTasks() can call the AppTask methods.
17470     */
17471    class AppTaskImpl extends IAppTask.Stub {
17472        private int mTaskId;
17473        private int mCallingUid;
17474
17475        public AppTaskImpl(int taskId, int callingUid) {
17476            mTaskId = taskId;
17477            mCallingUid = callingUid;
17478        }
17479
17480        @Override
17481        public void finishAndRemoveTask() {
17482            // Ensure that we are called from the same process that created this AppTask
17483            if (mCallingUid != Binder.getCallingUid()) {
17484                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17485                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17486                return;
17487            }
17488
17489            synchronized (ActivityManagerService.this) {
17490                long origId = Binder.clearCallingIdentity();
17491                try {
17492                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17493                    if (tr != null) {
17494                        // Only kill the process if we are not a new document
17495                        int flags = tr.getBaseIntent().getFlags();
17496                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17497                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17498                        removeTaskByIdLocked(mTaskId,
17499                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17500                    }
17501                } finally {
17502                    Binder.restoreCallingIdentity(origId);
17503                }
17504            }
17505        }
17506
17507        @Override
17508        public ActivityManager.RecentTaskInfo getTaskInfo() {
17509            // Ensure that we are called from the same process that created this AppTask
17510            if (mCallingUid != Binder.getCallingUid()) {
17511                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17512                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17513                return null;
17514            }
17515
17516            synchronized (ActivityManagerService.this) {
17517                long origId = Binder.clearCallingIdentity();
17518                try {
17519                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17520                    if (tr != null) {
17521                        return createRecentTaskInfoFromTaskRecord(tr);
17522                    }
17523                } finally {
17524                    Binder.restoreCallingIdentity(origId);
17525                }
17526                return null;
17527            }
17528        }
17529    }
17530}
17531