ActivityManagerService.java revision 810c052d9b117217152c2a609ccec056a2a61d1e
1/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import static android.Manifest.permission.INTERACT_ACROSS_USERS;
20import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
21import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
22import static android.content.pm.PackageManager.PERMISSION_GRANTED;
23import static com.android.internal.util.XmlUtils.readBooleanAttribute;
24import static com.android.internal.util.XmlUtils.readIntAttribute;
25import static com.android.internal.util.XmlUtils.readLongAttribute;
26import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
27import static com.android.internal.util.XmlUtils.writeIntAttribute;
28import static com.android.internal.util.XmlUtils.writeLongAttribute;
29import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST;
30import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
31import static org.xmlpull.v1.XmlPullParser.START_TAG;
32import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
33
34import android.Manifest;
35import android.app.AppOpsManager;
36import android.app.IActivityContainer;
37import android.app.IActivityContainerCallback;
38import android.app.IAppTask;
39import android.app.admin.DevicePolicyManager;
40import android.app.usage.UsageStats;
41import android.app.usage.UsageStatsManagerInternal;
42import android.appwidget.AppWidgetManager;
43import android.graphics.Rect;
44import android.os.BatteryStats;
45import android.os.PersistableBundle;
46import android.service.voice.IVoiceInteractionSession;
47import android.util.ArrayMap;
48import android.util.ArraySet;
49import android.util.SparseIntArray;
50
51import com.android.internal.R;
52import com.android.internal.annotations.GuardedBy;
53import com.android.internal.app.IAppOpsService;
54import com.android.internal.app.IVoiceInteractor;
55import com.android.internal.app.ProcessMap;
56import com.android.internal.app.ProcessStats;
57import com.android.internal.content.PackageMonitor;
58import com.android.internal.os.BackgroundThread;
59import com.android.internal.os.BatteryStatsImpl;
60import com.android.internal.os.ProcessCpuTracker;
61import com.android.internal.os.TransferPipe;
62import com.android.internal.os.Zygote;
63import com.android.internal.util.FastPrintWriter;
64import com.android.internal.util.FastXmlSerializer;
65import com.android.internal.util.MemInfoReader;
66import com.android.internal.util.Preconditions;
67import com.android.server.AppOpsService;
68import com.android.server.AttributeCache;
69import com.android.server.IntentResolver;
70import com.android.server.LocalServices;
71import com.android.server.ServiceThread;
72import com.android.server.SystemService;
73import com.android.server.SystemServiceManager;
74import com.android.server.Watchdog;
75import com.android.server.am.ActivityStack.ActivityState;
76import com.android.server.firewall.IntentFirewall;
77import com.android.server.pm.UserManagerService;
78import com.android.server.wm.AppTransition;
79import com.android.server.wm.WindowManagerService;
80import com.google.android.collect.Lists;
81import com.google.android.collect.Maps;
82
83import libcore.io.IoUtils;
84
85import org.xmlpull.v1.XmlPullParser;
86import org.xmlpull.v1.XmlPullParserException;
87import org.xmlpull.v1.XmlSerializer;
88
89import android.app.Activity;
90import android.app.ActivityManager;
91import android.app.ActivityManager.RunningTaskInfo;
92import android.app.ActivityManager.StackInfo;
93import android.app.ActivityManagerInternal;
94import android.app.ActivityManagerNative;
95import android.app.ActivityOptions;
96import android.app.ActivityThread;
97import android.app.AlertDialog;
98import android.app.AppGlobals;
99import android.app.ApplicationErrorReport;
100import android.app.Dialog;
101import android.app.IActivityController;
102import android.app.IApplicationThread;
103import android.app.IInstrumentationWatcher;
104import android.app.INotificationManager;
105import android.app.IProcessObserver;
106import android.app.IServiceConnection;
107import android.app.IStopUserCallback;
108import android.app.IUiAutomationConnection;
109import android.app.IUserSwitchObserver;
110import android.app.Instrumentation;
111import android.app.Notification;
112import android.app.NotificationManager;
113import android.app.PendingIntent;
114import android.app.backup.IBackupManager;
115import android.content.ActivityNotFoundException;
116import android.content.BroadcastReceiver;
117import android.content.ClipData;
118import android.content.ComponentCallbacks2;
119import android.content.ComponentName;
120import android.content.ContentProvider;
121import android.content.ContentResolver;
122import android.content.Context;
123import android.content.DialogInterface;
124import android.content.IContentProvider;
125import android.content.IIntentReceiver;
126import android.content.IIntentSender;
127import android.content.Intent;
128import android.content.IntentFilter;
129import android.content.IntentSender;
130import android.content.pm.ActivityInfo;
131import android.content.pm.ApplicationInfo;
132import android.content.pm.ConfigurationInfo;
133import android.content.pm.IPackageDataObserver;
134import android.content.pm.IPackageManager;
135import android.content.pm.InstrumentationInfo;
136import android.content.pm.PackageInfo;
137import android.content.pm.PackageManager;
138import android.content.pm.ParceledListSlice;
139import android.content.pm.UserInfo;
140import android.content.pm.PackageManager.NameNotFoundException;
141import android.content.pm.PathPermission;
142import android.content.pm.ProviderInfo;
143import android.content.pm.ResolveInfo;
144import android.content.pm.ServiceInfo;
145import android.content.res.CompatibilityInfo;
146import android.content.res.Configuration;
147import android.net.Proxy;
148import android.net.ProxyInfo;
149import android.net.Uri;
150import android.os.Binder;
151import android.os.Build;
152import android.os.Bundle;
153import android.os.Debug;
154import android.os.DropBoxManager;
155import android.os.Environment;
156import android.os.FactoryTest;
157import android.os.FileObserver;
158import android.os.FileUtils;
159import android.os.Handler;
160import android.os.IBinder;
161import android.os.IPermissionController;
162import android.os.IRemoteCallback;
163import android.os.IUserManager;
164import android.os.Looper;
165import android.os.Message;
166import android.os.Parcel;
167import android.os.ParcelFileDescriptor;
168import android.os.Process;
169import android.os.RemoteCallbackList;
170import android.os.RemoteException;
171import android.os.SELinux;
172import android.os.ServiceManager;
173import android.os.StrictMode;
174import android.os.SystemClock;
175import android.os.SystemProperties;
176import android.os.UpdateLock;
177import android.os.UserHandle;
178import android.provider.Settings;
179import android.text.format.DateUtils;
180import android.text.format.Time;
181import android.util.AtomicFile;
182import android.util.EventLog;
183import android.util.Log;
184import android.util.Pair;
185import android.util.PrintWriterPrinter;
186import android.util.Slog;
187import android.util.SparseArray;
188import android.util.TimeUtils;
189import android.util.Xml;
190import android.view.Gravity;
191import android.view.LayoutInflater;
192import android.view.View;
193import android.view.WindowManager;
194
195import java.io.BufferedInputStream;
196import java.io.BufferedOutputStream;
197import java.io.DataInputStream;
198import java.io.DataOutputStream;
199import java.io.File;
200import java.io.FileDescriptor;
201import java.io.FileInputStream;
202import java.io.FileNotFoundException;
203import java.io.FileOutputStream;
204import java.io.IOException;
205import java.io.InputStreamReader;
206import java.io.PrintWriter;
207import java.io.StringWriter;
208import java.lang.ref.WeakReference;
209import java.util.ArrayList;
210import java.util.Arrays;
211import java.util.Collections;
212import java.util.Comparator;
213import java.util.HashMap;
214import java.util.HashSet;
215import java.util.Iterator;
216import java.util.List;
217import java.util.Locale;
218import java.util.Map;
219import java.util.Set;
220import java.util.concurrent.atomic.AtomicBoolean;
221import java.util.concurrent.atomic.AtomicLong;
222
223public final class ActivityManagerService extends ActivityManagerNative
224        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
225
226    private static final String USER_DATA_DIR = "/data/user/";
227    // File that stores last updated system version and called preboot receivers
228    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
229
230    static final String TAG = "ActivityManager";
231    static final String TAG_MU = "ActivityManagerServiceMU";
232    static final boolean DEBUG = false;
233    static final boolean localLOGV = DEBUG;
234    static final boolean DEBUG_BACKUP = localLOGV || false;
235    static final boolean DEBUG_BROADCAST = localLOGV || false;
236    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
237    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
238    static final boolean DEBUG_CLEANUP = localLOGV || false;
239    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
240    static final boolean DEBUG_FOCUS = false;
241    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
242    static final boolean DEBUG_MU = localLOGV || false;
243    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
244    static final boolean DEBUG_LRU = localLOGV || false;
245    static final boolean DEBUG_PAUSE = localLOGV || false;
246    static final boolean DEBUG_POWER = localLOGV || false;
247    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
248    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
249    static final boolean DEBUG_PROCESSES = localLOGV || false;
250    static final boolean DEBUG_PROVIDER = localLOGV || false;
251    static final boolean DEBUG_RESULTS = localLOGV || false;
252    static final boolean DEBUG_SERVICE = localLOGV || false;
253    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
254    static final boolean DEBUG_STACK = localLOGV || false;
255    static final boolean DEBUG_SWITCH = localLOGV || false;
256    static final boolean DEBUG_TASKS = localLOGV || false;
257    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
258    static final boolean DEBUG_TRANSITION = localLOGV || false;
259    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
260    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
261    static final boolean DEBUG_VISBILITY = localLOGV || false;
262    static final boolean DEBUG_PSS = localLOGV || false;
263    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
264    static final boolean VALIDATE_TOKENS = false;
265    static final boolean SHOW_ACTIVITY_START_TIME = true;
266
267    // Control over CPU and battery monitoring.
268    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
269    static final boolean MONITOR_CPU_USAGE = true;
270    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
271    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
272    static final boolean MONITOR_THREAD_CPU_USAGE = false;
273
274    // The flags that are set for all calls we make to the package manager.
275    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
276
277    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
278
279    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
280
281    // Maximum number of recent tasks that we can remember.
282    static final int MAX_RECENT_TASKS = ActivityManager.isLowRamDeviceStatic() ? 100 : 200;
283
284    // Maximum number recent bitmaps to keep in memory.
285    static final int MAX_RECENT_BITMAPS = 5;
286
287    // Amount of time after a call to stopAppSwitches() during which we will
288    // prevent further untrusted switches from happening.
289    static final long APP_SWITCH_DELAY_TIME = 5*1000;
290
291    // How long we wait for a launched process to attach to the activity manager
292    // before we decide it's never going to come up for real.
293    static final int PROC_START_TIMEOUT = 10*1000;
294
295    // How long we wait for a launched process to attach to the activity manager
296    // before we decide it's never going to come up for real, when the process was
297    // started with a wrapper for instrumentation (such as Valgrind) because it
298    // could take much longer than usual.
299    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
300
301    // How long to wait after going idle before forcing apps to GC.
302    static final int GC_TIMEOUT = 5*1000;
303
304    // The minimum amount of time between successive GC requests for a process.
305    static final int GC_MIN_INTERVAL = 60*1000;
306
307    // The minimum amount of time between successive PSS requests for a process.
308    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process
311    // when the request is due to the memory state being lowered.
312    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
313
314    // The rate at which we check for apps using excessive power -- 15 mins.
315    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
316
317    // The minimum sample duration we will allow before deciding we have
318    // enough data on wake locks to start killing things.
319    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
320
321    // The minimum sample duration we will allow before deciding we have
322    // enough data on CPU usage to start killing things.
323    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
324
325    // How long we allow a receiver to run before giving up on it.
326    static final int BROADCAST_FG_TIMEOUT = 10*1000;
327    static final int BROADCAST_BG_TIMEOUT = 60*1000;
328
329    // How long we wait until we timeout on key dispatching.
330    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
331
332    // How long we wait until we timeout on key dispatching during instrumentation.
333    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
334
335    // Amount of time we wait for observers to handle a user switch before
336    // giving up on them and unfreezing the screen.
337    static final int USER_SWITCH_TIMEOUT = 2*1000;
338
339    // Maximum number of users we allow to be running at a time.
340    static final int MAX_RUNNING_USERS = 3;
341
342    // How long to wait in getAssistContextExtras for the activity and foreground services
343    // to respond with the result.
344    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
345
346    // Maximum number of persisted Uri grants a package is allowed
347    static final int MAX_PERSISTED_URI_GRANTS = 128;
348
349    static final int MY_PID = Process.myPid();
350
351    static final String[] EMPTY_STRING_ARRAY = new String[0];
352
353    // How many bytes to write into the dropbox log before truncating
354    static final int DROPBOX_MAX_SIZE = 256 * 1024;
355
356    // Access modes for handleIncomingUser.
357    static final int ALLOW_NON_FULL = 0;
358    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
359    static final int ALLOW_FULL_ONLY = 2;
360
361    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
362
363    /** All system services */
364    SystemServiceManager mSystemServiceManager;
365
366    /** Run all ActivityStacks through this */
367    ActivityStackSupervisor mStackSupervisor;
368
369    public IntentFirewall mIntentFirewall;
370
371    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
372    // default actuion automatically.  Important for devices without direct input
373    // devices.
374    private boolean mShowDialogs = true;
375
376    BroadcastQueue mFgBroadcastQueue;
377    BroadcastQueue mBgBroadcastQueue;
378    // Convenient for easy iteration over the queues. Foreground is first
379    // so that dispatch of foreground broadcasts gets precedence.
380    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
381
382    BroadcastQueue broadcastQueueForIntent(Intent intent) {
383        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
384        if (DEBUG_BACKGROUND_BROADCAST) {
385            Slog.i(TAG, "Broadcast intent " + intent + " on "
386                    + (isFg ? "foreground" : "background")
387                    + " queue");
388        }
389        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
390    }
391
392    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
393        for (BroadcastQueue queue : mBroadcastQueues) {
394            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
395            if (r != null) {
396                return r;
397            }
398        }
399        return null;
400    }
401
402    /**
403     * Activity we have told the window manager to have key focus.
404     */
405    ActivityRecord mFocusedActivity = null;
406
407    /**
408     * List of intents that were used to start the most recent tasks.
409     */
410    ArrayList<TaskRecord> mRecentTasks;
411    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
412
413    public class PendingAssistExtras extends Binder implements Runnable {
414        public final ActivityRecord activity;
415        public boolean haveResult = false;
416        public Bundle result = null;
417        public PendingAssistExtras(ActivityRecord _activity) {
418            activity = _activity;
419        }
420        @Override
421        public void run() {
422            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
423            synchronized (this) {
424                haveResult = true;
425                notifyAll();
426            }
427        }
428    }
429
430    final ArrayList<PendingAssistExtras> mPendingAssistExtras
431            = new ArrayList<PendingAssistExtras>();
432
433    /**
434     * Process management.
435     */
436    final ProcessList mProcessList = new ProcessList();
437
438    /**
439     * All of the applications we currently have running organized by name.
440     * The keys are strings of the application package name (as
441     * returned by the package manager), and the keys are ApplicationRecord
442     * objects.
443     */
444    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
445
446    /**
447     * Tracking long-term execution of processes to look for abuse and other
448     * bad app behavior.
449     */
450    final ProcessStatsService mProcessStats;
451
452    /**
453     * The currently running isolated processes.
454     */
455    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
456
457    /**
458     * Counter for assigning isolated process uids, to avoid frequently reusing the
459     * same ones.
460     */
461    int mNextIsolatedProcessUid = 0;
462
463    /**
464     * The currently running heavy-weight process, if any.
465     */
466    ProcessRecord mHeavyWeightProcess = null;
467
468    /**
469     * The last time that various processes have crashed.
470     */
471    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
472
473    /**
474     * Information about a process that is currently marked as bad.
475     */
476    static final class BadProcessInfo {
477        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
478            this.time = time;
479            this.shortMsg = shortMsg;
480            this.longMsg = longMsg;
481            this.stack = stack;
482        }
483
484        final long time;
485        final String shortMsg;
486        final String longMsg;
487        final String stack;
488    }
489
490    /**
491     * Set of applications that we consider to be bad, and will reject
492     * incoming broadcasts from (which the user has no control over).
493     * Processes are added to this set when they have crashed twice within
494     * a minimum amount of time; they are removed from it when they are
495     * later restarted (hopefully due to some user action).  The value is the
496     * time it was added to the list.
497     */
498    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
499
500    /**
501     * All of the processes we currently have running organized by pid.
502     * The keys are the pid running the application.
503     *
504     * <p>NOTE: This object is protected by its own lock, NOT the global
505     * activity manager lock!
506     */
507    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
508
509    /**
510     * All of the processes that have been forced to be foreground.  The key
511     * is the pid of the caller who requested it (we hold a death
512     * link on it).
513     */
514    abstract class ForegroundToken implements IBinder.DeathRecipient {
515        int pid;
516        IBinder token;
517    }
518    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
519
520    /**
521     * List of records for processes that someone had tried to start before the
522     * system was ready.  We don't start them at that point, but ensure they
523     * are started by the time booting is complete.
524     */
525    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
526
527    /**
528     * List of persistent applications that are in the process
529     * of being started.
530     */
531    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
532
533    /**
534     * Processes that are being forcibly torn down.
535     */
536    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
537
538    /**
539     * List of running applications, sorted by recent usage.
540     * The first entry in the list is the least recently used.
541     */
542    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
543
544    /**
545     * Where in mLruProcesses that the processes hosting activities start.
546     */
547    int mLruProcessActivityStart = 0;
548
549    /**
550     * Where in mLruProcesses that the processes hosting services start.
551     * This is after (lower index) than mLruProcessesActivityStart.
552     */
553    int mLruProcessServiceStart = 0;
554
555    /**
556     * List of processes that should gc as soon as things are idle.
557     */
558    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
559
560    /**
561     * Processes we want to collect PSS data from.
562     */
563    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
564
565    /**
566     * Last time we requested PSS data of all processes.
567     */
568    long mLastFullPssTime = SystemClock.uptimeMillis();
569
570    /**
571     * If set, the next time we collect PSS data we should do a full collection
572     * with data from native processes and the kernel.
573     */
574    boolean mFullPssPending = false;
575
576    /**
577     * This is the process holding what we currently consider to be
578     * the "home" activity.
579     */
580    ProcessRecord mHomeProcess;
581
582    /**
583     * This is the process holding the activity the user last visited that
584     * is in a different process from the one they are currently in.
585     */
586    ProcessRecord mPreviousProcess;
587
588    /**
589     * The time at which the previous process was last visible.
590     */
591    long mPreviousProcessVisibleTime;
592
593    /**
594     * Which uses have been started, so are allowed to run code.
595     */
596    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
597
598    /**
599     * LRU list of history of current users.  Most recently current is at the end.
600     */
601    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
602
603    /**
604     * Constant array of the users that are currently started.
605     */
606    int[] mStartedUserArray = new int[] { 0 };
607
608    /**
609     * Registered observers of the user switching mechanics.
610     */
611    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
612            = new RemoteCallbackList<IUserSwitchObserver>();
613
614    /**
615     * Currently active user switch.
616     */
617    Object mCurUserSwitchCallback;
618
619    /**
620     * Packages that the user has asked to have run in screen size
621     * compatibility mode instead of filling the screen.
622     */
623    final CompatModePackages mCompatModePackages;
624
625    /**
626     * Set of IntentSenderRecord objects that are currently active.
627     */
628    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
629            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
630
631    /**
632     * Fingerprints (hashCode()) of stack traces that we've
633     * already logged DropBox entries for.  Guarded by itself.  If
634     * something (rogue user app) forces this over
635     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
636     */
637    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
638    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
639
640    /**
641     * Strict Mode background batched logging state.
642     *
643     * The string buffer is guarded by itself, and its lock is also
644     * used to determine if another batched write is already
645     * in-flight.
646     */
647    private final StringBuilder mStrictModeBuffer = new StringBuilder();
648
649    /**
650     * Keeps track of all IIntentReceivers that have been registered for
651     * broadcasts.  Hash keys are the receiver IBinder, hash value is
652     * a ReceiverList.
653     */
654    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
655            new HashMap<IBinder, ReceiverList>();
656
657    /**
658     * Resolver for broadcast intents to registered receivers.
659     * Holds BroadcastFilter (subclass of IntentFilter).
660     */
661    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
662            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
663        @Override
664        protected boolean allowFilterResult(
665                BroadcastFilter filter, List<BroadcastFilter> dest) {
666            IBinder target = filter.receiverList.receiver.asBinder();
667            for (int i=dest.size()-1; i>=0; i--) {
668                if (dest.get(i).receiverList.receiver.asBinder() == target) {
669                    return false;
670                }
671            }
672            return true;
673        }
674
675        @Override
676        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
677            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
678                    || userId == filter.owningUserId) {
679                return super.newResult(filter, match, userId);
680            }
681            return null;
682        }
683
684        @Override
685        protected BroadcastFilter[] newArray(int size) {
686            return new BroadcastFilter[size];
687        }
688
689        @Override
690        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
691            return packageName.equals(filter.packageName);
692        }
693    };
694
695    /**
696     * State of all active sticky broadcasts per user.  Keys are the action of the
697     * sticky Intent, values are an ArrayList of all broadcasted intents with
698     * that action (which should usually be one).  The SparseArray is keyed
699     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
700     * for stickies that are sent to all users.
701     */
702    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
703            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
704
705    final ActiveServices mServices;
706
707    /**
708     * Backup/restore process management
709     */
710    String mBackupAppName = null;
711    BackupRecord mBackupTarget = null;
712
713    final ProviderMap mProviderMap;
714
715    /**
716     * List of content providers who have clients waiting for them.  The
717     * application is currently being launched and the provider will be
718     * removed from this list once it is published.
719     */
720    final ArrayList<ContentProviderRecord> mLaunchingProviders
721            = new ArrayList<ContentProviderRecord>();
722
723    /**
724     * File storing persisted {@link #mGrantedUriPermissions}.
725     */
726    private final AtomicFile mGrantFile;
727
728    /** XML constants used in {@link #mGrantFile} */
729    private static final String TAG_URI_GRANTS = "uri-grants";
730    private static final String TAG_URI_GRANT = "uri-grant";
731    private static final String ATTR_USER_HANDLE = "userHandle";
732    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
733    private static final String ATTR_TARGET_USER_ID = "targetUserId";
734    private static final String ATTR_SOURCE_PKG = "sourcePkg";
735    private static final String ATTR_TARGET_PKG = "targetPkg";
736    private static final String ATTR_URI = "uri";
737    private static final String ATTR_MODE_FLAGS = "modeFlags";
738    private static final String ATTR_CREATED_TIME = "createdTime";
739    private static final String ATTR_PREFIX = "prefix";
740
741    /**
742     * Global set of specific {@link Uri} permissions that have been granted.
743     * This optimized lookup structure maps from {@link UriPermission#targetUid}
744     * to {@link UriPermission#uri} to {@link UriPermission}.
745     */
746    @GuardedBy("this")
747    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
748            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
749
750    public static class GrantUri {
751        public final int sourceUserId;
752        public final Uri uri;
753        public boolean prefix;
754
755        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
756            this.sourceUserId = sourceUserId;
757            this.uri = uri;
758            this.prefix = prefix;
759        }
760
761        @Override
762        public int hashCode() {
763            return toString().hashCode();
764        }
765
766        @Override
767        public boolean equals(Object o) {
768            if (o instanceof GrantUri) {
769                GrantUri other = (GrantUri) o;
770                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
771                        && prefix == other.prefix;
772            }
773            return false;
774        }
775
776        @Override
777        public String toString() {
778            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
779            if (prefix) result += " [prefix]";
780            return result;
781        }
782
783        public String toSafeString() {
784            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
785            if (prefix) result += " [prefix]";
786            return result;
787        }
788
789        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
790            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
791                    ContentProvider.getUriWithoutUserId(uri), false);
792        }
793    }
794
795    CoreSettingsObserver mCoreSettingsObserver;
796
797    /**
798     * Thread-local storage used to carry caller permissions over through
799     * indirect content-provider access.
800     */
801    private class Identity {
802        public int pid;
803        public int uid;
804
805        Identity(int _pid, int _uid) {
806            pid = _pid;
807            uid = _uid;
808        }
809    }
810
811    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
812
813    /**
814     * All information we have collected about the runtime performance of
815     * any user id that can impact battery performance.
816     */
817    final BatteryStatsService mBatteryStatsService;
818
819    /**
820     * Information about component usage
821     */
822    UsageStatsManagerInternal mUsageStatsService;
823
824    /**
825     * Information about and control over application operations
826     */
827    final AppOpsService mAppOpsService;
828
829    /**
830     * Save recent tasks information across reboots.
831     */
832    final TaskPersister mTaskPersister;
833
834    /**
835     * Current configuration information.  HistoryRecord objects are given
836     * a reference to this object to indicate which configuration they are
837     * currently running in, so this object must be kept immutable.
838     */
839    Configuration mConfiguration = new Configuration();
840
841    /**
842     * Current sequencing integer of the configuration, for skipping old
843     * configurations.
844     */
845    int mConfigurationSeq = 0;
846
847    /**
848     * Hardware-reported OpenGLES version.
849     */
850    final int GL_ES_VERSION;
851
852    /**
853     * List of initialization arguments to pass to all processes when binding applications to them.
854     * For example, references to the commonly used services.
855     */
856    HashMap<String, IBinder> mAppBindArgs;
857
858    /**
859     * Temporary to avoid allocations.  Protected by main lock.
860     */
861    final StringBuilder mStringBuilder = new StringBuilder(256);
862
863    /**
864     * Used to control how we initialize the service.
865     */
866    ComponentName mTopComponent;
867    String mTopAction = Intent.ACTION_MAIN;
868    String mTopData;
869    boolean mProcessesReady = false;
870    boolean mSystemReady = false;
871    boolean mBooting = false;
872    boolean mWaitingUpdate = false;
873    boolean mDidUpdate = false;
874    boolean mOnBattery = false;
875    boolean mLaunchWarningShown = false;
876
877    Context mContext;
878
879    int mFactoryTest;
880
881    boolean mCheckedForSetup;
882
883    /**
884     * The time at which we will allow normal application switches again,
885     * after a call to {@link #stopAppSwitches()}.
886     */
887    long mAppSwitchesAllowedTime;
888
889    /**
890     * This is set to true after the first switch after mAppSwitchesAllowedTime
891     * is set; any switches after that will clear the time.
892     */
893    boolean mDidAppSwitch;
894
895    /**
896     * Last time (in realtime) at which we checked for power usage.
897     */
898    long mLastPowerCheckRealtime;
899
900    /**
901     * Last time (in uptime) at which we checked for power usage.
902     */
903    long mLastPowerCheckUptime;
904
905    /**
906     * Set while we are wanting to sleep, to prevent any
907     * activities from being started/resumed.
908     */
909    private boolean mSleeping = false;
910
911    /**
912     * Set while we are running a voice interaction.  This overrides
913     * sleeping while it is active.
914     */
915    private boolean mRunningVoice = false;
916
917    /**
918     * State of external calls telling us if the device is asleep.
919     */
920    private boolean mWentToSleep = false;
921
922    /**
923     * State of external call telling us if the lock screen is shown.
924     */
925    private boolean mLockScreenShown = false;
926
927    /**
928     * Set if we are shutting down the system, similar to sleeping.
929     */
930    boolean mShuttingDown = false;
931
932    /**
933     * Current sequence id for oom_adj computation traversal.
934     */
935    int mAdjSeq = 0;
936
937    /**
938     * Current sequence id for process LRU updating.
939     */
940    int mLruSeq = 0;
941
942    /**
943     * Keep track of the non-cached/empty process we last found, to help
944     * determine how to distribute cached/empty processes next time.
945     */
946    int mNumNonCachedProcs = 0;
947
948    /**
949     * Keep track of the number of cached hidden procs, to balance oom adj
950     * distribution between those and empty procs.
951     */
952    int mNumCachedHiddenProcs = 0;
953
954    /**
955     * Keep track of the number of service processes we last found, to
956     * determine on the next iteration which should be B services.
957     */
958    int mNumServiceProcs = 0;
959    int mNewNumAServiceProcs = 0;
960    int mNewNumServiceProcs = 0;
961
962    /**
963     * Allow the current computed overall memory level of the system to go down?
964     * This is set to false when we are killing processes for reasons other than
965     * memory management, so that the now smaller process list will not be taken as
966     * an indication that memory is tighter.
967     */
968    boolean mAllowLowerMemLevel = false;
969
970    /**
971     * The last computed memory level, for holding when we are in a state that
972     * processes are going away for other reasons.
973     */
974    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
975
976    /**
977     * The last total number of process we have, to determine if changes actually look
978     * like a shrinking number of process due to lower RAM.
979     */
980    int mLastNumProcesses;
981
982    /**
983     * The uptime of the last time we performed idle maintenance.
984     */
985    long mLastIdleTime = SystemClock.uptimeMillis();
986
987    /**
988     * Total time spent with RAM that has been added in the past since the last idle time.
989     */
990    long mLowRamTimeSinceLastIdle = 0;
991
992    /**
993     * If RAM is currently low, when that horrible situation started.
994     */
995    long mLowRamStartTime = 0;
996
997    /**
998     * For reporting to battery stats the current top application.
999     */
1000    private String mCurResumedPackage = null;
1001    private int mCurResumedUid = -1;
1002
1003    /**
1004     * For reporting to battery stats the apps currently running foreground
1005     * service.  The ProcessMap is package/uid tuples; each of these contain
1006     * an array of the currently foreground processes.
1007     */
1008    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1009            = new ProcessMap<ArrayList<ProcessRecord>>();
1010
1011    /**
1012     * This is set if we had to do a delayed dexopt of an app before launching
1013     * it, to increase the ANR timeouts in that case.
1014     */
1015    boolean mDidDexOpt;
1016
1017    /**
1018     * Set if the systemServer made a call to enterSafeMode.
1019     */
1020    boolean mSafeMode;
1021
1022    String mDebugApp = null;
1023    boolean mWaitForDebugger = false;
1024    boolean mDebugTransient = false;
1025    String mOrigDebugApp = null;
1026    boolean mOrigWaitForDebugger = false;
1027    boolean mAlwaysFinishActivities = false;
1028    IActivityController mController = null;
1029    String mProfileApp = null;
1030    ProcessRecord mProfileProc = null;
1031    String mProfileFile;
1032    ParcelFileDescriptor mProfileFd;
1033    int mProfileType = 0;
1034    boolean mAutoStopProfiler = false;
1035    String mOpenGlTraceApp = null;
1036
1037    static class ProcessChangeItem {
1038        static final int CHANGE_ACTIVITIES = 1<<0;
1039        static final int CHANGE_PROCESS_STATE = 1<<1;
1040        int changes;
1041        int uid;
1042        int pid;
1043        int processState;
1044        boolean foregroundActivities;
1045    }
1046
1047    final RemoteCallbackList<IProcessObserver> mProcessObservers
1048            = new RemoteCallbackList<IProcessObserver>();
1049    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1050
1051    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1052            = new ArrayList<ProcessChangeItem>();
1053    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1054            = new ArrayList<ProcessChangeItem>();
1055
1056    /**
1057     * Runtime CPU use collection thread.  This object's lock is used to
1058     * protect all related state.
1059     */
1060    final Thread mProcessCpuThread;
1061
1062    /**
1063     * Used to collect process stats when showing not responding dialog.
1064     * Protected by mProcessCpuThread.
1065     */
1066    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1067            MONITOR_THREAD_CPU_USAGE);
1068    final AtomicLong mLastCpuTime = new AtomicLong(0);
1069    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1070
1071    long mLastWriteTime = 0;
1072
1073    /**
1074     * Used to retain an update lock when the foreground activity is in
1075     * immersive mode.
1076     */
1077    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1078
1079    /**
1080     * Set to true after the system has finished booting.
1081     */
1082    boolean mBooted = false;
1083
1084    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1085    int mProcessLimitOverride = -1;
1086
1087    WindowManagerService mWindowManager;
1088
1089    final ActivityThread mSystemThread;
1090
1091    int mCurrentUserId = 0;
1092    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1093
1094    /**
1095     * Mapping from each known user ID to the profile group ID it is associated with.
1096     */
1097    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1098
1099    private UserManagerService mUserManager;
1100
1101    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1102        final ProcessRecord mApp;
1103        final int mPid;
1104        final IApplicationThread mAppThread;
1105
1106        AppDeathRecipient(ProcessRecord app, int pid,
1107                IApplicationThread thread) {
1108            if (localLOGV) Slog.v(
1109                TAG, "New death recipient " + this
1110                + " for thread " + thread.asBinder());
1111            mApp = app;
1112            mPid = pid;
1113            mAppThread = thread;
1114        }
1115
1116        @Override
1117        public void binderDied() {
1118            if (localLOGV) Slog.v(
1119                TAG, "Death received in " + this
1120                + " for thread " + mAppThread.asBinder());
1121            synchronized(ActivityManagerService.this) {
1122                appDiedLocked(mApp, mPid, mAppThread);
1123            }
1124        }
1125    }
1126
1127    static final int SHOW_ERROR_MSG = 1;
1128    static final int SHOW_NOT_RESPONDING_MSG = 2;
1129    static final int SHOW_FACTORY_ERROR_MSG = 3;
1130    static final int UPDATE_CONFIGURATION_MSG = 4;
1131    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1132    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1133    static final int SERVICE_TIMEOUT_MSG = 12;
1134    static final int UPDATE_TIME_ZONE = 13;
1135    static final int SHOW_UID_ERROR_MSG = 14;
1136    static final int IM_FEELING_LUCKY_MSG = 15;
1137    static final int PROC_START_TIMEOUT_MSG = 20;
1138    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1139    static final int KILL_APPLICATION_MSG = 22;
1140    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1141    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1142    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1143    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1144    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1145    static final int CLEAR_DNS_CACHE_MSG = 28;
1146    static final int UPDATE_HTTP_PROXY_MSG = 29;
1147    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1148    static final int DISPATCH_PROCESSES_CHANGED = 31;
1149    static final int DISPATCH_PROCESS_DIED = 32;
1150    static final int REPORT_MEM_USAGE_MSG = 33;
1151    static final int REPORT_USER_SWITCH_MSG = 34;
1152    static final int CONTINUE_USER_SWITCH_MSG = 35;
1153    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1154    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1155    static final int PERSIST_URI_GRANTS_MSG = 38;
1156    static final int REQUEST_ALL_PSS_MSG = 39;
1157    static final int START_PROFILES_MSG = 40;
1158    static final int UPDATE_TIME = 41;
1159    static final int SYSTEM_USER_START_MSG = 42;
1160    static final int SYSTEM_USER_CURRENT_MSG = 43;
1161    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1162    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1163
1164    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1165    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1166    static final int FIRST_COMPAT_MODE_MSG = 300;
1167    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1168
1169    AlertDialog mUidAlert;
1170    CompatModeDialog mCompatModeDialog;
1171    long mLastMemUsageReportTime = 0;
1172
1173    private LockToAppRequestDialog mLockToAppRequest;
1174
1175    /**
1176     * Flag whether the current user is a "monkey", i.e. whether
1177     * the UI is driven by a UI automation tool.
1178     */
1179    private boolean mUserIsMonkey;
1180
1181    /** Flag whether the device has a recents UI */
1182    final boolean mHasRecents;
1183
1184    final ServiceThread mHandlerThread;
1185    final MainHandler mHandler;
1186
1187    final class MainHandler extends Handler {
1188        public MainHandler(Looper looper) {
1189            super(looper, null, true);
1190        }
1191
1192        @Override
1193        public void handleMessage(Message msg) {
1194            switch (msg.what) {
1195            case SHOW_ERROR_MSG: {
1196                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1197                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1198                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1199                synchronized (ActivityManagerService.this) {
1200                    ProcessRecord proc = (ProcessRecord)data.get("app");
1201                    AppErrorResult res = (AppErrorResult) data.get("result");
1202                    if (proc != null && proc.crashDialog != null) {
1203                        Slog.e(TAG, "App already has crash dialog: " + proc);
1204                        if (res != null) {
1205                            res.set(0);
1206                        }
1207                        return;
1208                    }
1209                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1210                            >= Process.FIRST_APPLICATION_UID
1211                            && proc.pid != MY_PID);
1212                    for (int userId : mCurrentProfileIds) {
1213                        isBackground &= (proc.userId != userId);
1214                    }
1215                    if (isBackground && !showBackground) {
1216                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1217                        if (res != null) {
1218                            res.set(0);
1219                        }
1220                        return;
1221                    }
1222                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1223                        Dialog d = new AppErrorDialog(mContext,
1224                                ActivityManagerService.this, res, proc);
1225                        d.show();
1226                        proc.crashDialog = d;
1227                    } else {
1228                        // The device is asleep, so just pretend that the user
1229                        // saw a crash dialog and hit "force quit".
1230                        if (res != null) {
1231                            res.set(0);
1232                        }
1233                    }
1234                }
1235
1236                ensureBootCompleted();
1237            } break;
1238            case SHOW_NOT_RESPONDING_MSG: {
1239                synchronized (ActivityManagerService.this) {
1240                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1241                    ProcessRecord proc = (ProcessRecord)data.get("app");
1242                    if (proc != null && proc.anrDialog != null) {
1243                        Slog.e(TAG, "App already has anr dialog: " + proc);
1244                        return;
1245                    }
1246
1247                    Intent intent = new Intent("android.intent.action.ANR");
1248                    if (!mProcessesReady) {
1249                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1250                                | Intent.FLAG_RECEIVER_FOREGROUND);
1251                    }
1252                    broadcastIntentLocked(null, null, intent,
1253                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1254                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1255
1256                    if (mShowDialogs) {
1257                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1258                                mContext, proc, (ActivityRecord)data.get("activity"),
1259                                msg.arg1 != 0);
1260                        d.show();
1261                        proc.anrDialog = d;
1262                    } else {
1263                        // Just kill the app if there is no dialog to be shown.
1264                        killAppAtUsersRequest(proc, null);
1265                    }
1266                }
1267
1268                ensureBootCompleted();
1269            } break;
1270            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1271                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1272                synchronized (ActivityManagerService.this) {
1273                    ProcessRecord proc = (ProcessRecord) data.get("app");
1274                    if (proc == null) {
1275                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1276                        break;
1277                    }
1278                    if (proc.crashDialog != null) {
1279                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1280                        return;
1281                    }
1282                    AppErrorResult res = (AppErrorResult) data.get("result");
1283                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1284                        Dialog d = new StrictModeViolationDialog(mContext,
1285                                ActivityManagerService.this, res, proc);
1286                        d.show();
1287                        proc.crashDialog = d;
1288                    } else {
1289                        // The device is asleep, so just pretend that the user
1290                        // saw a crash dialog and hit "force quit".
1291                        res.set(0);
1292                    }
1293                }
1294                ensureBootCompleted();
1295            } break;
1296            case SHOW_FACTORY_ERROR_MSG: {
1297                Dialog d = new FactoryErrorDialog(
1298                    mContext, msg.getData().getCharSequence("msg"));
1299                d.show();
1300                ensureBootCompleted();
1301            } break;
1302            case UPDATE_CONFIGURATION_MSG: {
1303                final ContentResolver resolver = mContext.getContentResolver();
1304                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1305            } break;
1306            case GC_BACKGROUND_PROCESSES_MSG: {
1307                synchronized (ActivityManagerService.this) {
1308                    performAppGcsIfAppropriateLocked();
1309                }
1310            } break;
1311            case WAIT_FOR_DEBUGGER_MSG: {
1312                synchronized (ActivityManagerService.this) {
1313                    ProcessRecord app = (ProcessRecord)msg.obj;
1314                    if (msg.arg1 != 0) {
1315                        if (!app.waitedForDebugger) {
1316                            Dialog d = new AppWaitingForDebuggerDialog(
1317                                    ActivityManagerService.this,
1318                                    mContext, app);
1319                            app.waitDialog = d;
1320                            app.waitedForDebugger = true;
1321                            d.show();
1322                        }
1323                    } else {
1324                        if (app.waitDialog != null) {
1325                            app.waitDialog.dismiss();
1326                            app.waitDialog = null;
1327                        }
1328                    }
1329                }
1330            } break;
1331            case SERVICE_TIMEOUT_MSG: {
1332                if (mDidDexOpt) {
1333                    mDidDexOpt = false;
1334                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1335                    nmsg.obj = msg.obj;
1336                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1337                    return;
1338                }
1339                mServices.serviceTimeout((ProcessRecord)msg.obj);
1340            } break;
1341            case UPDATE_TIME_ZONE: {
1342                synchronized (ActivityManagerService.this) {
1343                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1344                        ProcessRecord r = mLruProcesses.get(i);
1345                        if (r.thread != null) {
1346                            try {
1347                                r.thread.updateTimeZone();
1348                            } catch (RemoteException ex) {
1349                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1350                            }
1351                        }
1352                    }
1353                }
1354            } break;
1355            case CLEAR_DNS_CACHE_MSG: {
1356                synchronized (ActivityManagerService.this) {
1357                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1358                        ProcessRecord r = mLruProcesses.get(i);
1359                        if (r.thread != null) {
1360                            try {
1361                                r.thread.clearDnsCache();
1362                            } catch (RemoteException ex) {
1363                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1364                            }
1365                        }
1366                    }
1367                }
1368            } break;
1369            case UPDATE_HTTP_PROXY_MSG: {
1370                ProxyInfo proxy = (ProxyInfo)msg.obj;
1371                String host = "";
1372                String port = "";
1373                String exclList = "";
1374                Uri pacFileUrl = Uri.EMPTY;
1375                if (proxy != null) {
1376                    host = proxy.getHost();
1377                    port = Integer.toString(proxy.getPort());
1378                    exclList = proxy.getExclusionListAsString();
1379                    pacFileUrl = proxy.getPacFileUrl();
1380                }
1381                synchronized (ActivityManagerService.this) {
1382                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1383                        ProcessRecord r = mLruProcesses.get(i);
1384                        if (r.thread != null) {
1385                            try {
1386                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1387                            } catch (RemoteException ex) {
1388                                Slog.w(TAG, "Failed to update http proxy for: " +
1389                                        r.info.processName);
1390                            }
1391                        }
1392                    }
1393                }
1394            } break;
1395            case SHOW_UID_ERROR_MSG: {
1396                String title = "System UIDs Inconsistent";
1397                String text = "UIDs on the system are inconsistent, you need to wipe your"
1398                        + " data partition or your device will be unstable.";
1399                Log.e(TAG, title + ": " + text);
1400                if (mShowDialogs) {
1401                    // XXX This is a temporary dialog, no need to localize.
1402                    AlertDialog d = new BaseErrorDialog(mContext);
1403                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1404                    d.setCancelable(false);
1405                    d.setTitle(title);
1406                    d.setMessage(text);
1407                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1408                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1409                    mUidAlert = d;
1410                    d.show();
1411                }
1412            } break;
1413            case IM_FEELING_LUCKY_MSG: {
1414                if (mUidAlert != null) {
1415                    mUidAlert.dismiss();
1416                    mUidAlert = null;
1417                }
1418            } break;
1419            case PROC_START_TIMEOUT_MSG: {
1420                if (mDidDexOpt) {
1421                    mDidDexOpt = false;
1422                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1423                    nmsg.obj = msg.obj;
1424                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1425                    return;
1426                }
1427                ProcessRecord app = (ProcessRecord)msg.obj;
1428                synchronized (ActivityManagerService.this) {
1429                    processStartTimedOutLocked(app);
1430                }
1431            } break;
1432            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1433                synchronized (ActivityManagerService.this) {
1434                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1435                }
1436            } break;
1437            case KILL_APPLICATION_MSG: {
1438                synchronized (ActivityManagerService.this) {
1439                    int appid = msg.arg1;
1440                    boolean restart = (msg.arg2 == 1);
1441                    Bundle bundle = (Bundle)msg.obj;
1442                    String pkg = bundle.getString("pkg");
1443                    String reason = bundle.getString("reason");
1444                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1445                            false, UserHandle.USER_ALL, reason);
1446                }
1447            } break;
1448            case FINALIZE_PENDING_INTENT_MSG: {
1449                ((PendingIntentRecord)msg.obj).completeFinalize();
1450            } break;
1451            case POST_HEAVY_NOTIFICATION_MSG: {
1452                INotificationManager inm = NotificationManager.getService();
1453                if (inm == null) {
1454                    return;
1455                }
1456
1457                ActivityRecord root = (ActivityRecord)msg.obj;
1458                ProcessRecord process = root.app;
1459                if (process == null) {
1460                    return;
1461                }
1462
1463                try {
1464                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1465                    String text = mContext.getString(R.string.heavy_weight_notification,
1466                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1467                    Notification notification = new Notification();
1468                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1469                    notification.when = 0;
1470                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1471                    notification.tickerText = text;
1472                    notification.defaults = 0; // please be quiet
1473                    notification.sound = null;
1474                    notification.vibrate = null;
1475                    notification.setLatestEventInfo(context, text,
1476                            mContext.getText(R.string.heavy_weight_notification_detail),
1477                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1478                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1479                                    new UserHandle(root.userId)));
1480
1481                    try {
1482                        int[] outId = new int[1];
1483                        inm.enqueueNotificationWithTag("android", "android", null,
1484                                R.string.heavy_weight_notification,
1485                                notification, outId, root.userId);
1486                    } catch (RuntimeException e) {
1487                        Slog.w(ActivityManagerService.TAG,
1488                                "Error showing notification for heavy-weight app", e);
1489                    } catch (RemoteException e) {
1490                    }
1491                } catch (NameNotFoundException e) {
1492                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1493                }
1494            } break;
1495            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1496                INotificationManager inm = NotificationManager.getService();
1497                if (inm == null) {
1498                    return;
1499                }
1500                try {
1501                    inm.cancelNotificationWithTag("android", null,
1502                            R.string.heavy_weight_notification,  msg.arg1);
1503                } catch (RuntimeException e) {
1504                    Slog.w(ActivityManagerService.TAG,
1505                            "Error canceling notification for service", e);
1506                } catch (RemoteException e) {
1507                }
1508            } break;
1509            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1510                synchronized (ActivityManagerService.this) {
1511                    checkExcessivePowerUsageLocked(true);
1512                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1513                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1514                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1515                }
1516            } break;
1517            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1518                synchronized (ActivityManagerService.this) {
1519                    ActivityRecord ar = (ActivityRecord)msg.obj;
1520                    if (mCompatModeDialog != null) {
1521                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1522                                ar.info.applicationInfo.packageName)) {
1523                            return;
1524                        }
1525                        mCompatModeDialog.dismiss();
1526                        mCompatModeDialog = null;
1527                    }
1528                    if (ar != null && false) {
1529                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1530                                ar.packageName)) {
1531                            int mode = mCompatModePackages.computeCompatModeLocked(
1532                                    ar.info.applicationInfo);
1533                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1534                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1535                                mCompatModeDialog = new CompatModeDialog(
1536                                        ActivityManagerService.this, mContext,
1537                                        ar.info.applicationInfo);
1538                                mCompatModeDialog.show();
1539                            }
1540                        }
1541                    }
1542                }
1543                break;
1544            }
1545            case DISPATCH_PROCESSES_CHANGED: {
1546                dispatchProcessesChanged();
1547                break;
1548            }
1549            case DISPATCH_PROCESS_DIED: {
1550                final int pid = msg.arg1;
1551                final int uid = msg.arg2;
1552                dispatchProcessDied(pid, uid);
1553                break;
1554            }
1555            case REPORT_MEM_USAGE_MSG: {
1556                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1557                Thread thread = new Thread() {
1558                    @Override public void run() {
1559                        final SparseArray<ProcessMemInfo> infoMap
1560                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1561                        for (int i=0, N=memInfos.size(); i<N; i++) {
1562                            ProcessMemInfo mi = memInfos.get(i);
1563                            infoMap.put(mi.pid, mi);
1564                        }
1565                        updateCpuStatsNow();
1566                        synchronized (mProcessCpuThread) {
1567                            final int N = mProcessCpuTracker.countStats();
1568                            for (int i=0; i<N; i++) {
1569                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1570                                if (st.vsize > 0) {
1571                                    long pss = Debug.getPss(st.pid, null);
1572                                    if (pss > 0) {
1573                                        if (infoMap.indexOfKey(st.pid) < 0) {
1574                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1575                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1576                                            mi.pss = pss;
1577                                            memInfos.add(mi);
1578                                        }
1579                                    }
1580                                }
1581                            }
1582                        }
1583
1584                        long totalPss = 0;
1585                        for (int i=0, N=memInfos.size(); i<N; i++) {
1586                            ProcessMemInfo mi = memInfos.get(i);
1587                            if (mi.pss == 0) {
1588                                mi.pss = Debug.getPss(mi.pid, null);
1589                            }
1590                            totalPss += mi.pss;
1591                        }
1592                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1593                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1594                                if (lhs.oomAdj != rhs.oomAdj) {
1595                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1596                                }
1597                                if (lhs.pss != rhs.pss) {
1598                                    return lhs.pss < rhs.pss ? 1 : -1;
1599                                }
1600                                return 0;
1601                            }
1602                        });
1603
1604                        StringBuilder tag = new StringBuilder(128);
1605                        StringBuilder stack = new StringBuilder(128);
1606                        tag.append("Low on memory -- ");
1607                        appendMemBucket(tag, totalPss, "total", false);
1608                        appendMemBucket(stack, totalPss, "total", true);
1609
1610                        StringBuilder logBuilder = new StringBuilder(1024);
1611                        logBuilder.append("Low on memory:\n");
1612
1613                        boolean firstLine = true;
1614                        int lastOomAdj = Integer.MIN_VALUE;
1615                        for (int i=0, N=memInfos.size(); i<N; i++) {
1616                            ProcessMemInfo mi = memInfos.get(i);
1617
1618                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1619                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1620                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1621                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1622                                if (lastOomAdj != mi.oomAdj) {
1623                                    lastOomAdj = mi.oomAdj;
1624                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1625                                        tag.append(" / ");
1626                                    }
1627                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1628                                        if (firstLine) {
1629                                            stack.append(":");
1630                                            firstLine = false;
1631                                        }
1632                                        stack.append("\n\t at ");
1633                                    } else {
1634                                        stack.append("$");
1635                                    }
1636                                } else {
1637                                    tag.append(" ");
1638                                    stack.append("$");
1639                                }
1640                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1641                                    appendMemBucket(tag, mi.pss, mi.name, false);
1642                                }
1643                                appendMemBucket(stack, mi.pss, mi.name, true);
1644                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1645                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1646                                    stack.append("(");
1647                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1648                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1649                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1650                                            stack.append(":");
1651                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1652                                        }
1653                                    }
1654                                    stack.append(")");
1655                                }
1656                            }
1657
1658                            logBuilder.append("  ");
1659                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1660                            logBuilder.append(' ');
1661                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1662                            logBuilder.append(' ');
1663                            ProcessList.appendRamKb(logBuilder, mi.pss);
1664                            logBuilder.append(" kB: ");
1665                            logBuilder.append(mi.name);
1666                            logBuilder.append(" (");
1667                            logBuilder.append(mi.pid);
1668                            logBuilder.append(") ");
1669                            logBuilder.append(mi.adjType);
1670                            logBuilder.append('\n');
1671                            if (mi.adjReason != null) {
1672                                logBuilder.append("                      ");
1673                                logBuilder.append(mi.adjReason);
1674                                logBuilder.append('\n');
1675                            }
1676                        }
1677
1678                        logBuilder.append("           ");
1679                        ProcessList.appendRamKb(logBuilder, totalPss);
1680                        logBuilder.append(" kB: TOTAL\n");
1681
1682                        long[] infos = new long[Debug.MEMINFO_COUNT];
1683                        Debug.getMemInfo(infos);
1684                        logBuilder.append("  MemInfo: ");
1685                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1686                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1687                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1688                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1689                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1690                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1691                            logBuilder.append("  ZRAM: ");
1692                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1693                            logBuilder.append(" kB RAM, ");
1694                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1695                            logBuilder.append(" kB swap total, ");
1696                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1697                            logBuilder.append(" kB swap free\n");
1698                        }
1699                        Slog.i(TAG, logBuilder.toString());
1700
1701                        StringBuilder dropBuilder = new StringBuilder(1024);
1702                        /*
1703                        StringWriter oomSw = new StringWriter();
1704                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1705                        StringWriter catSw = new StringWriter();
1706                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1707                        String[] emptyArgs = new String[] { };
1708                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1709                        oomPw.flush();
1710                        String oomString = oomSw.toString();
1711                        */
1712                        dropBuilder.append(stack);
1713                        dropBuilder.append('\n');
1714                        dropBuilder.append('\n');
1715                        dropBuilder.append(logBuilder);
1716                        dropBuilder.append('\n');
1717                        /*
1718                        dropBuilder.append(oomString);
1719                        dropBuilder.append('\n');
1720                        */
1721                        StringWriter catSw = new StringWriter();
1722                        synchronized (ActivityManagerService.this) {
1723                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1724                            String[] emptyArgs = new String[] { };
1725                            catPw.println();
1726                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1727                            catPw.println();
1728                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1729                                    false, false, null);
1730                            catPw.println();
1731                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1732                            catPw.flush();
1733                        }
1734                        dropBuilder.append(catSw.toString());
1735                        addErrorToDropBox("lowmem", null, "system_server", null,
1736                                null, tag.toString(), dropBuilder.toString(), null, null);
1737                        //Slog.i(TAG, "Sent to dropbox:");
1738                        //Slog.i(TAG, dropBuilder.toString());
1739                        synchronized (ActivityManagerService.this) {
1740                            long now = SystemClock.uptimeMillis();
1741                            if (mLastMemUsageReportTime < now) {
1742                                mLastMemUsageReportTime = now;
1743                            }
1744                        }
1745                    }
1746                };
1747                thread.start();
1748                break;
1749            }
1750            case REPORT_USER_SWITCH_MSG: {
1751                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1752                break;
1753            }
1754            case CONTINUE_USER_SWITCH_MSG: {
1755                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1756                break;
1757            }
1758            case USER_SWITCH_TIMEOUT_MSG: {
1759                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1760                break;
1761            }
1762            case IMMERSIVE_MODE_LOCK_MSG: {
1763                final boolean nextState = (msg.arg1 != 0);
1764                if (mUpdateLock.isHeld() != nextState) {
1765                    if (DEBUG_IMMERSIVE) {
1766                        final ActivityRecord r = (ActivityRecord) msg.obj;
1767                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1768                    }
1769                    if (nextState) {
1770                        mUpdateLock.acquire();
1771                    } else {
1772                        mUpdateLock.release();
1773                    }
1774                }
1775                break;
1776            }
1777            case PERSIST_URI_GRANTS_MSG: {
1778                writeGrantedUriPermissions();
1779                break;
1780            }
1781            case REQUEST_ALL_PSS_MSG: {
1782                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1783                break;
1784            }
1785            case START_PROFILES_MSG: {
1786                synchronized (ActivityManagerService.this) {
1787                    startProfilesLocked();
1788                }
1789                break;
1790            }
1791            case UPDATE_TIME: {
1792                synchronized (ActivityManagerService.this) {
1793                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1794                        ProcessRecord r = mLruProcesses.get(i);
1795                        if (r.thread != null) {
1796                            try {
1797                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1798                            } catch (RemoteException ex) {
1799                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1800                            }
1801                        }
1802                    }
1803                }
1804                break;
1805            }
1806            case SYSTEM_USER_START_MSG: {
1807                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1808                        Integer.toString(msg.arg1), msg.arg1);
1809                mSystemServiceManager.startUser(msg.arg1);
1810                break;
1811            }
1812            case SYSTEM_USER_CURRENT_MSG: {
1813                mBatteryStatsService.noteEvent(
1814                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1815                        Integer.toString(msg.arg2), msg.arg2);
1816                mBatteryStatsService.noteEvent(
1817                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1818                        Integer.toString(msg.arg1), msg.arg1);
1819                mSystemServiceManager.switchUser(msg.arg1);
1820                break;
1821            }
1822            case ENTER_ANIMATION_COMPLETE_MSG: {
1823                synchronized (ActivityManagerService.this) {
1824                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1825                    if (r != null && r.app != null && r.app.thread != null) {
1826                        try {
1827                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1828                        } catch (RemoteException e) {
1829                        }
1830                    }
1831                }
1832                break;
1833            }
1834            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1835                enableScreenAfterBoot();
1836                break;
1837            }
1838            }
1839        }
1840    };
1841
1842    static final int COLLECT_PSS_BG_MSG = 1;
1843
1844    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1845        @Override
1846        public void handleMessage(Message msg) {
1847            switch (msg.what) {
1848            case COLLECT_PSS_BG_MSG: {
1849                long start = SystemClock.uptimeMillis();
1850                MemInfoReader memInfo = null;
1851                synchronized (ActivityManagerService.this) {
1852                    if (mFullPssPending) {
1853                        mFullPssPending = false;
1854                        memInfo = new MemInfoReader();
1855                    }
1856                }
1857                if (memInfo != null) {
1858                    updateCpuStatsNow();
1859                    long nativeTotalPss = 0;
1860                    synchronized (mProcessCpuThread) {
1861                        final int N = mProcessCpuTracker.countStats();
1862                        for (int j=0; j<N; j++) {
1863                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1864                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1865                                // This is definitely an application process; skip it.
1866                                continue;
1867                            }
1868                            synchronized (mPidsSelfLocked) {
1869                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1870                                    // This is one of our own processes; skip it.
1871                                    continue;
1872                                }
1873                            }
1874                            nativeTotalPss += Debug.getPss(st.pid, null);
1875                        }
1876                    }
1877                    memInfo.readMemInfo();
1878                    synchronized (this) {
1879                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1880                                + (SystemClock.uptimeMillis()-start) + "ms");
1881                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1882                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1883                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1884                                        +memInfo.getSlabSizeKb(),
1885                                nativeTotalPss);
1886                    }
1887                }
1888
1889                int i=0, num=0;
1890                long[] tmp = new long[1];
1891                do {
1892                    ProcessRecord proc;
1893                    int procState;
1894                    int pid;
1895                    synchronized (ActivityManagerService.this) {
1896                        if (i >= mPendingPssProcesses.size()) {
1897                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1898                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1899                            mPendingPssProcesses.clear();
1900                            return;
1901                        }
1902                        proc = mPendingPssProcesses.get(i);
1903                        procState = proc.pssProcState;
1904                        if (proc.thread != null && procState == proc.setProcState) {
1905                            pid = proc.pid;
1906                        } else {
1907                            proc = null;
1908                            pid = 0;
1909                        }
1910                        i++;
1911                    }
1912                    if (proc != null) {
1913                        long pss = Debug.getPss(pid, tmp);
1914                        synchronized (ActivityManagerService.this) {
1915                            if (proc.thread != null && proc.setProcState == procState
1916                                    && proc.pid == pid) {
1917                                num++;
1918                                proc.lastPssTime = SystemClock.uptimeMillis();
1919                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1920                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1921                                        + ": " + pss + " lastPss=" + proc.lastPss
1922                                        + " state=" + ProcessList.makeProcStateString(procState));
1923                                if (proc.initialIdlePss == 0) {
1924                                    proc.initialIdlePss = pss;
1925                                }
1926                                proc.lastPss = pss;
1927                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1928                                    proc.lastCachedPss = pss;
1929                                }
1930                            }
1931                        }
1932                    }
1933                } while (true);
1934            }
1935            }
1936        }
1937    };
1938
1939    /**
1940     * Monitor for package changes and update our internal state.
1941     */
1942    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1943        @Override
1944        public void onPackageRemoved(String packageName, int uid) {
1945            // Remove all tasks with activities in the specified package from the list of recent tasks
1946            synchronized (ActivityManagerService.this) {
1947                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1948                    TaskRecord tr = mRecentTasks.get(i);
1949                    ComponentName cn = tr.intent.getComponent();
1950                    if (cn != null && cn.getPackageName().equals(packageName)) {
1951                        // If the package name matches, remove the task and kill the process
1952                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1953                    }
1954                }
1955            }
1956        }
1957
1958        @Override
1959        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1960            onPackageModified(packageName);
1961            return true;
1962        }
1963
1964        @Override
1965        public void onPackageModified(String packageName) {
1966            final PackageManager pm = mContext.getPackageManager();
1967            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1968                    new ArrayList<Pair<Intent, Integer>>();
1969            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
1970            // Copy the list of recent tasks so that we don't hold onto the lock on
1971            // ActivityManagerService for long periods while checking if components exist.
1972            synchronized (ActivityManagerService.this) {
1973                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1974                    TaskRecord tr = mRecentTasks.get(i);
1975                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
1976                }
1977            }
1978            // Check the recent tasks and filter out all tasks with components that no longer exist.
1979            Intent tmpI = new Intent();
1980            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
1981                Pair<Intent, Integer> p = recentTaskIntents.get(i);
1982                ComponentName cn = p.first.getComponent();
1983                if (cn != null && cn.getPackageName().equals(packageName)) {
1984                    try {
1985                        // Add the task to the list to remove if the component no longer exists
1986                        tmpI.setComponent(cn);
1987                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
1988                            tasksToRemove.add(p.second);
1989                        }
1990                    } catch (Exception e) {}
1991                }
1992            }
1993            // Prune all the tasks with removed components from the list of recent tasks
1994            synchronized (ActivityManagerService.this) {
1995                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
1996                    // Remove the task but don't kill the process (since other components in that
1997                    // package may still be running and in the background)
1998                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
1999                }
2000            }
2001        }
2002
2003        @Override
2004        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2005            // Force stop the specified packages
2006            if (packages != null) {
2007                for (String pkg : packages) {
2008                    synchronized (ActivityManagerService.this) {
2009                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2010                                "finished booting")) {
2011                            return true;
2012                        }
2013                    }
2014                }
2015            }
2016            return false;
2017        }
2018    };
2019
2020    public void setSystemProcess() {
2021        try {
2022            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2023            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2024            ServiceManager.addService("meminfo", new MemBinder(this));
2025            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2026            ServiceManager.addService("dbinfo", new DbBinder(this));
2027            if (MONITOR_CPU_USAGE) {
2028                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2029            }
2030            ServiceManager.addService("permission", new PermissionController(this));
2031
2032            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2033                    "android", STOCK_PM_FLAGS);
2034            mSystemThread.installSystemApplicationInfo(info);
2035
2036            synchronized (this) {
2037                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2038                app.persistent = true;
2039                app.pid = MY_PID;
2040                app.maxAdj = ProcessList.SYSTEM_ADJ;
2041                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2042                mProcessNames.put(app.processName, app.uid, app);
2043                synchronized (mPidsSelfLocked) {
2044                    mPidsSelfLocked.put(app.pid, app);
2045                }
2046                updateLruProcessLocked(app, false, null);
2047                updateOomAdjLocked();
2048            }
2049        } catch (PackageManager.NameNotFoundException e) {
2050            throw new RuntimeException(
2051                    "Unable to find android system package", e);
2052        }
2053    }
2054
2055    public void setWindowManager(WindowManagerService wm) {
2056        mWindowManager = wm;
2057        mStackSupervisor.setWindowManager(wm);
2058    }
2059
2060    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2061        mUsageStatsService = usageStatsManager;
2062    }
2063
2064    public void startObservingNativeCrashes() {
2065        final NativeCrashListener ncl = new NativeCrashListener(this);
2066        ncl.start();
2067    }
2068
2069    public IAppOpsService getAppOpsService() {
2070        return mAppOpsService;
2071    }
2072
2073    static class MemBinder extends Binder {
2074        ActivityManagerService mActivityManagerService;
2075        MemBinder(ActivityManagerService activityManagerService) {
2076            mActivityManagerService = activityManagerService;
2077        }
2078
2079        @Override
2080        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2081            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2082                    != PackageManager.PERMISSION_GRANTED) {
2083                pw.println("Permission Denial: can't dump meminfo from from pid="
2084                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2085                        + " without permission " + android.Manifest.permission.DUMP);
2086                return;
2087            }
2088
2089            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2090        }
2091    }
2092
2093    static class GraphicsBinder extends Binder {
2094        ActivityManagerService mActivityManagerService;
2095        GraphicsBinder(ActivityManagerService activityManagerService) {
2096            mActivityManagerService = activityManagerService;
2097        }
2098
2099        @Override
2100        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2101            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2102                    != PackageManager.PERMISSION_GRANTED) {
2103                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2104                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2105                        + " without permission " + android.Manifest.permission.DUMP);
2106                return;
2107            }
2108
2109            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2110        }
2111    }
2112
2113    static class DbBinder extends Binder {
2114        ActivityManagerService mActivityManagerService;
2115        DbBinder(ActivityManagerService activityManagerService) {
2116            mActivityManagerService = activityManagerService;
2117        }
2118
2119        @Override
2120        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2121            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2122                    != PackageManager.PERMISSION_GRANTED) {
2123                pw.println("Permission Denial: can't dump dbinfo from from pid="
2124                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2125                        + " without permission " + android.Manifest.permission.DUMP);
2126                return;
2127            }
2128
2129            mActivityManagerService.dumpDbInfo(fd, pw, args);
2130        }
2131    }
2132
2133    static class CpuBinder extends Binder {
2134        ActivityManagerService mActivityManagerService;
2135        CpuBinder(ActivityManagerService activityManagerService) {
2136            mActivityManagerService = activityManagerService;
2137        }
2138
2139        @Override
2140        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2141            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2142                    != PackageManager.PERMISSION_GRANTED) {
2143                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2144                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2145                        + " without permission " + android.Manifest.permission.DUMP);
2146                return;
2147            }
2148
2149            synchronized (mActivityManagerService.mProcessCpuThread) {
2150                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2151                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2152                        SystemClock.uptimeMillis()));
2153            }
2154        }
2155    }
2156
2157    public static final class Lifecycle extends SystemService {
2158        private final ActivityManagerService mService;
2159
2160        public Lifecycle(Context context) {
2161            super(context);
2162            mService = new ActivityManagerService(context);
2163        }
2164
2165        @Override
2166        public void onStart() {
2167            mService.start();
2168        }
2169
2170        public ActivityManagerService getService() {
2171            return mService;
2172        }
2173    }
2174
2175    // Note: This method is invoked on the main thread but may need to attach various
2176    // handlers to other threads.  So take care to be explicit about the looper.
2177    public ActivityManagerService(Context systemContext) {
2178        mContext = systemContext;
2179        mFactoryTest = FactoryTest.getMode();
2180        mSystemThread = ActivityThread.currentActivityThread();
2181
2182        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2183
2184        mHandlerThread = new ServiceThread(TAG,
2185                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2186        mHandlerThread.start();
2187        mHandler = new MainHandler(mHandlerThread.getLooper());
2188
2189        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2190                "foreground", BROADCAST_FG_TIMEOUT, false);
2191        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2192                "background", BROADCAST_BG_TIMEOUT, true);
2193        mBroadcastQueues[0] = mFgBroadcastQueue;
2194        mBroadcastQueues[1] = mBgBroadcastQueue;
2195
2196        mServices = new ActiveServices(this);
2197        mProviderMap = new ProviderMap(this);
2198
2199        // TODO: Move creation of battery stats service outside of activity manager service.
2200        File dataDir = Environment.getDataDirectory();
2201        File systemDir = new File(dataDir, "system");
2202        systemDir.mkdirs();
2203        mBatteryStatsService = new BatteryStatsService(new File(
2204                systemDir, "batterystats.bin").toString(), mHandler);
2205        mBatteryStatsService.getActiveStatistics().readLocked();
2206        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2207        mOnBattery = DEBUG_POWER ? true
2208                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2209        mBatteryStatsService.getActiveStatistics().setCallback(this);
2210
2211        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2212
2213        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2214
2215        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2216
2217        // User 0 is the first and only user that runs at boot.
2218        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2219        mUserLru.add(Integer.valueOf(0));
2220        updateStartedUserArrayLocked();
2221
2222        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2223            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2224
2225        mConfiguration.setToDefaults();
2226        mConfiguration.setLocale(Locale.getDefault());
2227
2228        mConfigurationSeq = mConfiguration.seq = 1;
2229        mProcessCpuTracker.init();
2230
2231        mHasRecents = mContext.getResources().getBoolean(
2232                com.android.internal.R.bool.config_hasRecents);
2233
2234        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2235        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2236        mStackSupervisor = new ActivityStackSupervisor(this);
2237        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2238
2239        mProcessCpuThread = new Thread("CpuTracker") {
2240            @Override
2241            public void run() {
2242                while (true) {
2243                    try {
2244                        try {
2245                            synchronized(this) {
2246                                final long now = SystemClock.uptimeMillis();
2247                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2248                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2249                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2250                                //        + ", write delay=" + nextWriteDelay);
2251                                if (nextWriteDelay < nextCpuDelay) {
2252                                    nextCpuDelay = nextWriteDelay;
2253                                }
2254                                if (nextCpuDelay > 0) {
2255                                    mProcessCpuMutexFree.set(true);
2256                                    this.wait(nextCpuDelay);
2257                                }
2258                            }
2259                        } catch (InterruptedException e) {
2260                        }
2261                        updateCpuStatsNow();
2262                    } catch (Exception e) {
2263                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2264                    }
2265                }
2266            }
2267        };
2268
2269        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2270
2271        Watchdog.getInstance().addMonitor(this);
2272        Watchdog.getInstance().addThread(mHandler);
2273    }
2274
2275    public void setSystemServiceManager(SystemServiceManager mgr) {
2276        mSystemServiceManager = mgr;
2277    }
2278
2279    private void start() {
2280        Process.removeAllProcessGroups();
2281        mProcessCpuThread.start();
2282
2283        mBatteryStatsService.publish(mContext);
2284        mAppOpsService.publish(mContext);
2285        Slog.d("AppOps", "AppOpsService published");
2286        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2287    }
2288
2289    public void initPowerManagement() {
2290        mStackSupervisor.initPowerManagement();
2291        mBatteryStatsService.initPowerManagement();
2292    }
2293
2294    @Override
2295    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2296            throws RemoteException {
2297        if (code == SYSPROPS_TRANSACTION) {
2298            // We need to tell all apps about the system property change.
2299            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2300            synchronized(this) {
2301                final int NP = mProcessNames.getMap().size();
2302                for (int ip=0; ip<NP; ip++) {
2303                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2304                    final int NA = apps.size();
2305                    for (int ia=0; ia<NA; ia++) {
2306                        ProcessRecord app = apps.valueAt(ia);
2307                        if (app.thread != null) {
2308                            procs.add(app.thread.asBinder());
2309                        }
2310                    }
2311                }
2312            }
2313
2314            int N = procs.size();
2315            for (int i=0; i<N; i++) {
2316                Parcel data2 = Parcel.obtain();
2317                try {
2318                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2319                } catch (RemoteException e) {
2320                }
2321                data2.recycle();
2322            }
2323        }
2324        try {
2325            return super.onTransact(code, data, reply, flags);
2326        } catch (RuntimeException e) {
2327            // The activity manager only throws security exceptions, so let's
2328            // log all others.
2329            if (!(e instanceof SecurityException)) {
2330                Slog.wtf(TAG, "Activity Manager Crash", e);
2331            }
2332            throw e;
2333        }
2334    }
2335
2336    void updateCpuStats() {
2337        final long now = SystemClock.uptimeMillis();
2338        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2339            return;
2340        }
2341        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2342            synchronized (mProcessCpuThread) {
2343                mProcessCpuThread.notify();
2344            }
2345        }
2346    }
2347
2348    void updateCpuStatsNow() {
2349        synchronized (mProcessCpuThread) {
2350            mProcessCpuMutexFree.set(false);
2351            final long now = SystemClock.uptimeMillis();
2352            boolean haveNewCpuStats = false;
2353
2354            if (MONITOR_CPU_USAGE &&
2355                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2356                mLastCpuTime.set(now);
2357                haveNewCpuStats = true;
2358                mProcessCpuTracker.update();
2359                //Slog.i(TAG, mProcessCpu.printCurrentState());
2360                //Slog.i(TAG, "Total CPU usage: "
2361                //        + mProcessCpu.getTotalCpuPercent() + "%");
2362
2363                // Slog the cpu usage if the property is set.
2364                if ("true".equals(SystemProperties.get("events.cpu"))) {
2365                    int user = mProcessCpuTracker.getLastUserTime();
2366                    int system = mProcessCpuTracker.getLastSystemTime();
2367                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2368                    int irq = mProcessCpuTracker.getLastIrqTime();
2369                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2370                    int idle = mProcessCpuTracker.getLastIdleTime();
2371
2372                    int total = user + system + iowait + irq + softIrq + idle;
2373                    if (total == 0) total = 1;
2374
2375                    EventLog.writeEvent(EventLogTags.CPU,
2376                            ((user+system+iowait+irq+softIrq) * 100) / total,
2377                            (user * 100) / total,
2378                            (system * 100) / total,
2379                            (iowait * 100) / total,
2380                            (irq * 100) / total,
2381                            (softIrq * 100) / total);
2382                }
2383            }
2384
2385            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2386            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2387            synchronized(bstats) {
2388                synchronized(mPidsSelfLocked) {
2389                    if (haveNewCpuStats) {
2390                        if (mOnBattery) {
2391                            int perc = bstats.startAddingCpuLocked();
2392                            int totalUTime = 0;
2393                            int totalSTime = 0;
2394                            final int N = mProcessCpuTracker.countStats();
2395                            for (int i=0; i<N; i++) {
2396                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2397                                if (!st.working) {
2398                                    continue;
2399                                }
2400                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2401                                int otherUTime = (st.rel_utime*perc)/100;
2402                                int otherSTime = (st.rel_stime*perc)/100;
2403                                totalUTime += otherUTime;
2404                                totalSTime += otherSTime;
2405                                if (pr != null) {
2406                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2407                                    if (ps == null || !ps.isActive()) {
2408                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2409                                                pr.info.uid, pr.processName);
2410                                    }
2411                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2412                                            st.rel_stime-otherSTime);
2413                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2414                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2415                                } else {
2416                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2417                                    if (ps == null || !ps.isActive()) {
2418                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2419                                                bstats.mapUid(st.uid), st.name);
2420                                    }
2421                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2422                                            st.rel_stime-otherSTime);
2423                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2424                                }
2425                            }
2426                            bstats.finishAddingCpuLocked(perc, totalUTime,
2427                                    totalSTime, cpuSpeedTimes);
2428                        }
2429                    }
2430                }
2431
2432                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2433                    mLastWriteTime = now;
2434                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2435                }
2436            }
2437        }
2438    }
2439
2440    @Override
2441    public void batteryNeedsCpuUpdate() {
2442        updateCpuStatsNow();
2443    }
2444
2445    @Override
2446    public void batteryPowerChanged(boolean onBattery) {
2447        // When plugging in, update the CPU stats first before changing
2448        // the plug state.
2449        updateCpuStatsNow();
2450        synchronized (this) {
2451            synchronized(mPidsSelfLocked) {
2452                mOnBattery = DEBUG_POWER ? true : onBattery;
2453            }
2454        }
2455    }
2456
2457    /**
2458     * Initialize the application bind args. These are passed to each
2459     * process when the bindApplication() IPC is sent to the process. They're
2460     * lazily setup to make sure the services are running when they're asked for.
2461     */
2462    private HashMap<String, IBinder> getCommonServicesLocked() {
2463        if (mAppBindArgs == null) {
2464            mAppBindArgs = new HashMap<String, IBinder>();
2465
2466            // Setup the application init args
2467            mAppBindArgs.put("package", ServiceManager.getService("package"));
2468            mAppBindArgs.put("window", ServiceManager.getService("window"));
2469            mAppBindArgs.put(Context.ALARM_SERVICE,
2470                    ServiceManager.getService(Context.ALARM_SERVICE));
2471        }
2472        return mAppBindArgs;
2473    }
2474
2475    final void setFocusedActivityLocked(ActivityRecord r) {
2476        if (mFocusedActivity != r) {
2477            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2478            mFocusedActivity = r;
2479            if (r.task != null && r.task.voiceInteractor != null) {
2480                startRunningVoiceLocked();
2481            } else {
2482                finishRunningVoiceLocked();
2483            }
2484            mStackSupervisor.setFocusedStack(r);
2485            if (r != null) {
2486                mWindowManager.setFocusedApp(r.appToken, true);
2487            }
2488            applyUpdateLockStateLocked(r);
2489        }
2490    }
2491
2492    final void clearFocusedActivity(ActivityRecord r) {
2493        if (mFocusedActivity == r) {
2494            mFocusedActivity = null;
2495        }
2496    }
2497
2498    @Override
2499    public void setFocusedStack(int stackId) {
2500        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2501        synchronized (ActivityManagerService.this) {
2502            ActivityStack stack = mStackSupervisor.getStack(stackId);
2503            if (stack != null) {
2504                ActivityRecord r = stack.topRunningActivityLocked(null);
2505                if (r != null) {
2506                    setFocusedActivityLocked(r);
2507                }
2508            }
2509        }
2510    }
2511
2512    @Override
2513    public void notifyActivityDrawn(IBinder token) {
2514        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2515        synchronized (this) {
2516            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2517            if (r != null) {
2518                r.task.stack.notifyActivityDrawnLocked(r);
2519            }
2520        }
2521    }
2522
2523    final void applyUpdateLockStateLocked(ActivityRecord r) {
2524        // Modifications to the UpdateLock state are done on our handler, outside
2525        // the activity manager's locks.  The new state is determined based on the
2526        // state *now* of the relevant activity record.  The object is passed to
2527        // the handler solely for logging detail, not to be consulted/modified.
2528        final boolean nextState = r != null && r.immersive;
2529        mHandler.sendMessage(
2530                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2531    }
2532
2533    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2534        Message msg = Message.obtain();
2535        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2536        msg.obj = r.task.askedCompatMode ? null : r;
2537        mHandler.sendMessage(msg);
2538    }
2539
2540    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2541            String what, Object obj, ProcessRecord srcApp) {
2542        app.lastActivityTime = now;
2543
2544        if (app.activities.size() > 0) {
2545            // Don't want to touch dependent processes that are hosting activities.
2546            return index;
2547        }
2548
2549        int lrui = mLruProcesses.lastIndexOf(app);
2550        if (lrui < 0) {
2551            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2552                    + what + " " + obj + " from " + srcApp);
2553            return index;
2554        }
2555
2556        if (lrui >= index) {
2557            // Don't want to cause this to move dependent processes *back* in the
2558            // list as if they were less frequently used.
2559            return index;
2560        }
2561
2562        if (lrui >= mLruProcessActivityStart) {
2563            // Don't want to touch dependent processes that are hosting activities.
2564            return index;
2565        }
2566
2567        mLruProcesses.remove(lrui);
2568        if (index > 0) {
2569            index--;
2570        }
2571        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2572                + " in LRU list: " + app);
2573        mLruProcesses.add(index, app);
2574        return index;
2575    }
2576
2577    final void removeLruProcessLocked(ProcessRecord app) {
2578        int lrui = mLruProcesses.lastIndexOf(app);
2579        if (lrui >= 0) {
2580            if (lrui <= mLruProcessActivityStart) {
2581                mLruProcessActivityStart--;
2582            }
2583            if (lrui <= mLruProcessServiceStart) {
2584                mLruProcessServiceStart--;
2585            }
2586            mLruProcesses.remove(lrui);
2587        }
2588    }
2589
2590    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2591            ProcessRecord client) {
2592        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2593                || app.treatLikeActivity;
2594        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2595        if (!activityChange && hasActivity) {
2596            // The process has activities, so we are only allowing activity-based adjustments
2597            // to move it.  It should be kept in the front of the list with other
2598            // processes that have activities, and we don't want those to change their
2599            // order except due to activity operations.
2600            return;
2601        }
2602
2603        mLruSeq++;
2604        final long now = SystemClock.uptimeMillis();
2605        app.lastActivityTime = now;
2606
2607        // First a quick reject: if the app is already at the position we will
2608        // put it, then there is nothing to do.
2609        if (hasActivity) {
2610            final int N = mLruProcesses.size();
2611            if (N > 0 && mLruProcesses.get(N-1) == app) {
2612                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2613                return;
2614            }
2615        } else {
2616            if (mLruProcessServiceStart > 0
2617                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2618                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2619                return;
2620            }
2621        }
2622
2623        int lrui = mLruProcesses.lastIndexOf(app);
2624
2625        if (app.persistent && lrui >= 0) {
2626            // We don't care about the position of persistent processes, as long as
2627            // they are in the list.
2628            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2629            return;
2630        }
2631
2632        /* In progress: compute new position first, so we can avoid doing work
2633           if the process is not actually going to move.  Not yet working.
2634        int addIndex;
2635        int nextIndex;
2636        boolean inActivity = false, inService = false;
2637        if (hasActivity) {
2638            // Process has activities, put it at the very tipsy-top.
2639            addIndex = mLruProcesses.size();
2640            nextIndex = mLruProcessServiceStart;
2641            inActivity = true;
2642        } else if (hasService) {
2643            // Process has services, put it at the top of the service list.
2644            addIndex = mLruProcessActivityStart;
2645            nextIndex = mLruProcessServiceStart;
2646            inActivity = true;
2647            inService = true;
2648        } else  {
2649            // Process not otherwise of interest, it goes to the top of the non-service area.
2650            addIndex = mLruProcessServiceStart;
2651            if (client != null) {
2652                int clientIndex = mLruProcesses.lastIndexOf(client);
2653                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2654                        + app);
2655                if (clientIndex >= 0 && addIndex > clientIndex) {
2656                    addIndex = clientIndex;
2657                }
2658            }
2659            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2660        }
2661
2662        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2663                + mLruProcessActivityStart + "): " + app);
2664        */
2665
2666        if (lrui >= 0) {
2667            if (lrui < mLruProcessActivityStart) {
2668                mLruProcessActivityStart--;
2669            }
2670            if (lrui < mLruProcessServiceStart) {
2671                mLruProcessServiceStart--;
2672            }
2673            /*
2674            if (addIndex > lrui) {
2675                addIndex--;
2676            }
2677            if (nextIndex > lrui) {
2678                nextIndex--;
2679            }
2680            */
2681            mLruProcesses.remove(lrui);
2682        }
2683
2684        /*
2685        mLruProcesses.add(addIndex, app);
2686        if (inActivity) {
2687            mLruProcessActivityStart++;
2688        }
2689        if (inService) {
2690            mLruProcessActivityStart++;
2691        }
2692        */
2693
2694        int nextIndex;
2695        if (hasActivity) {
2696            final int N = mLruProcesses.size();
2697            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2698                // Process doesn't have activities, but has clients with
2699                // activities...  move it up, but one below the top (the top
2700                // should always have a real activity).
2701                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2702                mLruProcesses.add(N-1, app);
2703                // To keep it from spamming the LRU list (by making a bunch of clients),
2704                // we will push down any other entries owned by the app.
2705                final int uid = app.info.uid;
2706                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2707                    ProcessRecord subProc = mLruProcesses.get(i);
2708                    if (subProc.info.uid == uid) {
2709                        // We want to push this one down the list.  If the process after
2710                        // it is for the same uid, however, don't do so, because we don't
2711                        // want them internally to be re-ordered.
2712                        if (mLruProcesses.get(i-1).info.uid != uid) {
2713                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2714                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2715                            ProcessRecord tmp = mLruProcesses.get(i);
2716                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2717                            mLruProcesses.set(i-1, tmp);
2718                            i--;
2719                        }
2720                    } else {
2721                        // A gap, we can stop here.
2722                        break;
2723                    }
2724                }
2725            } else {
2726                // Process has activities, put it at the very tipsy-top.
2727                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2728                mLruProcesses.add(app);
2729            }
2730            nextIndex = mLruProcessServiceStart;
2731        } else if (hasService) {
2732            // Process has services, put it at the top of the service list.
2733            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2734            mLruProcesses.add(mLruProcessActivityStart, app);
2735            nextIndex = mLruProcessServiceStart;
2736            mLruProcessActivityStart++;
2737        } else  {
2738            // Process not otherwise of interest, it goes to the top of the non-service area.
2739            int index = mLruProcessServiceStart;
2740            if (client != null) {
2741                // If there is a client, don't allow the process to be moved up higher
2742                // in the list than that client.
2743                int clientIndex = mLruProcesses.lastIndexOf(client);
2744                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2745                        + " when updating " + app);
2746                if (clientIndex <= lrui) {
2747                    // Don't allow the client index restriction to push it down farther in the
2748                    // list than it already is.
2749                    clientIndex = lrui;
2750                }
2751                if (clientIndex >= 0 && index > clientIndex) {
2752                    index = clientIndex;
2753                }
2754            }
2755            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2756            mLruProcesses.add(index, app);
2757            nextIndex = index-1;
2758            mLruProcessActivityStart++;
2759            mLruProcessServiceStart++;
2760        }
2761
2762        // If the app is currently using a content provider or service,
2763        // bump those processes as well.
2764        for (int j=app.connections.size()-1; j>=0; j--) {
2765            ConnectionRecord cr = app.connections.valueAt(j);
2766            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2767                    && cr.binding.service.app != null
2768                    && cr.binding.service.app.lruSeq != mLruSeq
2769                    && !cr.binding.service.app.persistent) {
2770                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2771                        "service connection", cr, app);
2772            }
2773        }
2774        for (int j=app.conProviders.size()-1; j>=0; j--) {
2775            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2776            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2777                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2778                        "provider reference", cpr, app);
2779            }
2780        }
2781    }
2782
2783    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2784        if (uid == Process.SYSTEM_UID) {
2785            // The system gets to run in any process.  If there are multiple
2786            // processes with the same uid, just pick the first (this
2787            // should never happen).
2788            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2789            if (procs == null) return null;
2790            final int N = procs.size();
2791            for (int i = 0; i < N; i++) {
2792                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2793            }
2794        }
2795        ProcessRecord proc = mProcessNames.get(processName, uid);
2796        if (false && proc != null && !keepIfLarge
2797                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2798                && proc.lastCachedPss >= 4000) {
2799            // Turn this condition on to cause killing to happen regularly, for testing.
2800            if (proc.baseProcessTracker != null) {
2801                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2802            }
2803            killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2804                    + "k from cached");
2805        } else if (proc != null && !keepIfLarge
2806                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2807                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2808            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2809            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2810                if (proc.baseProcessTracker != null) {
2811                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2812                }
2813                killUnneededProcessLocked(proc, Long.toString(proc.lastCachedPss)
2814                        + "k from cached");
2815            }
2816        }
2817        return proc;
2818    }
2819
2820    void ensurePackageDexOpt(String packageName) {
2821        IPackageManager pm = AppGlobals.getPackageManager();
2822        try {
2823            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2824                mDidDexOpt = true;
2825            }
2826        } catch (RemoteException e) {
2827        }
2828    }
2829
2830    boolean isNextTransitionForward() {
2831        int transit = mWindowManager.getPendingAppTransition();
2832        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2833                || transit == AppTransition.TRANSIT_TASK_OPEN
2834                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2835    }
2836
2837    final ProcessRecord startProcessLocked(String processName,
2838            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2839            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2840            boolean isolated, boolean keepIfLarge) {
2841        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2842                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2843                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2844                null /* crashHandler */);
2845    }
2846
2847    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2848            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2849            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2850            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2851        ProcessRecord app;
2852        if (!isolated) {
2853            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2854        } else {
2855            // If this is an isolated process, it can't re-use an existing process.
2856            app = null;
2857        }
2858        // We don't have to do anything more if:
2859        // (1) There is an existing application record; and
2860        // (2) The caller doesn't think it is dead, OR there is no thread
2861        //     object attached to it so we know it couldn't have crashed; and
2862        // (3) There is a pid assigned to it, so it is either starting or
2863        //     already running.
2864        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2865                + " app=" + app + " knownToBeDead=" + knownToBeDead
2866                + " thread=" + (app != null ? app.thread : null)
2867                + " pid=" + (app != null ? app.pid : -1));
2868        if (app != null && app.pid > 0) {
2869            if (!knownToBeDead || app.thread == null) {
2870                // We already have the app running, or are waiting for it to
2871                // come up (we have a pid but not yet its thread), so keep it.
2872                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2873                // If this is a new package in the process, add the package to the list
2874                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2875                return app;
2876            }
2877
2878            // An application record is attached to a previous process,
2879            // clean it up now.
2880            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2881            Process.killProcessGroup(app.info.uid, app.pid);
2882            handleAppDiedLocked(app, true, true);
2883        }
2884
2885        String hostingNameStr = hostingName != null
2886                ? hostingName.flattenToShortString() : null;
2887
2888        if (!isolated) {
2889            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2890                // If we are in the background, then check to see if this process
2891                // is bad.  If so, we will just silently fail.
2892                if (mBadProcesses.get(info.processName, info.uid) != null) {
2893                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2894                            + "/" + info.processName);
2895                    return null;
2896                }
2897            } else {
2898                // When the user is explicitly starting a process, then clear its
2899                // crash count so that we won't make it bad until they see at
2900                // least one crash dialog again, and make the process good again
2901                // if it had been bad.
2902                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2903                        + "/" + info.processName);
2904                mProcessCrashTimes.remove(info.processName, info.uid);
2905                if (mBadProcesses.get(info.processName, info.uid) != null) {
2906                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2907                            UserHandle.getUserId(info.uid), info.uid,
2908                            info.processName);
2909                    mBadProcesses.remove(info.processName, info.uid);
2910                    if (app != null) {
2911                        app.bad = false;
2912                    }
2913                }
2914            }
2915        }
2916
2917        if (app == null) {
2918            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2919            app.crashHandler = crashHandler;
2920            if (app == null) {
2921                Slog.w(TAG, "Failed making new process record for "
2922                        + processName + "/" + info.uid + " isolated=" + isolated);
2923                return null;
2924            }
2925            mProcessNames.put(processName, app.uid, app);
2926            if (isolated) {
2927                mIsolatedProcesses.put(app.uid, app);
2928            }
2929        } else {
2930            // If this is a new package in the process, add the package to the list
2931            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2932        }
2933
2934        // If the system is not ready yet, then hold off on starting this
2935        // process until it is.
2936        if (!mProcessesReady
2937                && !isAllowedWhileBooting(info)
2938                && !allowWhileBooting) {
2939            if (!mProcessesOnHold.contains(app)) {
2940                mProcessesOnHold.add(app);
2941            }
2942            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2943            return app;
2944        }
2945
2946        startProcessLocked(
2947                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2948        return (app.pid != 0) ? app : null;
2949    }
2950
2951    boolean isAllowedWhileBooting(ApplicationInfo ai) {
2952        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2953    }
2954
2955    private final void startProcessLocked(ProcessRecord app, String hostingType,
2956            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
2957        boolean isActivityProcess = (entryPoint == null);
2958        if (entryPoint == null) entryPoint = "android.app.ActivityThread";
2959        if (app.pid > 0 && app.pid != MY_PID) {
2960            synchronized (mPidsSelfLocked) {
2961                mPidsSelfLocked.remove(app.pid);
2962                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2963            }
2964            app.setPid(0);
2965        }
2966
2967        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2968                "startProcessLocked removing on hold: " + app);
2969        mProcessesOnHold.remove(app);
2970
2971        updateCpuStats();
2972
2973        try {
2974            int uid = app.uid;
2975
2976            int[] gids = null;
2977            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
2978            if (!app.isolated) {
2979                int[] permGids = null;
2980                try {
2981                    final PackageManager pm = mContext.getPackageManager();
2982                    permGids = pm.getPackageGids(app.info.packageName);
2983
2984                    if (Environment.isExternalStorageEmulated()) {
2985                        if (pm.checkPermission(
2986                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2987                                app.info.packageName) == PERMISSION_GRANTED) {
2988                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2989                        } else {
2990                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2991                        }
2992                    }
2993                } catch (PackageManager.NameNotFoundException e) {
2994                    Slog.w(TAG, "Unable to retrieve gids", e);
2995                }
2996
2997                /*
2998                 * Add shared application and profile GIDs so applications can share some
2999                 * resources like shared libraries and access user-wide resources
3000                 */
3001                if (permGids == null) {
3002                    gids = new int[2];
3003                } else {
3004                    gids = new int[permGids.length + 2];
3005                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3006                }
3007                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3008                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3009            }
3010            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3011                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3012                        && mTopComponent != null
3013                        && app.processName.equals(mTopComponent.getPackageName())) {
3014                    uid = 0;
3015                }
3016                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3017                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3018                    uid = 0;
3019                }
3020            }
3021            int debugFlags = 0;
3022            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3023                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3024                // Also turn on CheckJNI for debuggable apps. It's quite
3025                // awkward to turn on otherwise.
3026                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3027            }
3028            // Run the app in safe mode if its manifest requests so or the
3029            // system is booted in safe mode.
3030            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3031                mSafeMode == true) {
3032                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3033            }
3034            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3035                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3036            }
3037            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3038                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3039            }
3040            if ("1".equals(SystemProperties.get("debug.assert"))) {
3041                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3042            }
3043
3044            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3045            if (requiredAbi == null) {
3046                requiredAbi = Build.SUPPORTED_ABIS[0];
3047            }
3048
3049            // Start the process.  It will either succeed and return a result containing
3050            // the PID of the new process, or else throw a RuntimeException.
3051            Process.ProcessStartResult startResult = Process.start(entryPoint,
3052                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3053                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3054
3055            if (app.isolated) {
3056                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3057            }
3058            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3059
3060            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3061                    UserHandle.getUserId(uid), startResult.pid, uid,
3062                    app.processName, hostingType,
3063                    hostingNameStr != null ? hostingNameStr : "");
3064
3065            if (app.persistent) {
3066                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3067            }
3068
3069            StringBuilder buf = mStringBuilder;
3070            buf.setLength(0);
3071            buf.append("Start proc ");
3072            buf.append(app.processName);
3073            if (!isActivityProcess) {
3074                buf.append(" [");
3075                buf.append(entryPoint);
3076                buf.append("]");
3077            }
3078            buf.append(" for ");
3079            buf.append(hostingType);
3080            if (hostingNameStr != null) {
3081                buf.append(" ");
3082                buf.append(hostingNameStr);
3083            }
3084            buf.append(": pid=");
3085            buf.append(startResult.pid);
3086            buf.append(" uid=");
3087            buf.append(uid);
3088            buf.append(" gids={");
3089            if (gids != null) {
3090                for (int gi=0; gi<gids.length; gi++) {
3091                    if (gi != 0) buf.append(", ");
3092                    buf.append(gids[gi]);
3093
3094                }
3095            }
3096            buf.append("}");
3097            if (requiredAbi != null) {
3098                buf.append(" abi=");
3099                buf.append(requiredAbi);
3100            }
3101            Slog.i(TAG, buf.toString());
3102            app.setPid(startResult.pid);
3103            app.usingWrapper = startResult.usingWrapper;
3104            app.removed = false;
3105            app.killedByAm = false;
3106            synchronized (mPidsSelfLocked) {
3107                this.mPidsSelfLocked.put(startResult.pid, app);
3108                if (isActivityProcess) {
3109                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3110                    msg.obj = app;
3111                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3112                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3113                }
3114            }
3115        } catch (RuntimeException e) {
3116            // XXX do better error recovery.
3117            app.setPid(0);
3118            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3119            if (app.isolated) {
3120                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3121            }
3122            Slog.e(TAG, "Failure starting process " + app.processName, e);
3123        }
3124    }
3125
3126    void updateUsageStats(ActivityRecord component, boolean resumed) {
3127        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3128        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3129        if (resumed) {
3130            if (mUsageStatsService != null) {
3131                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3132                        System.currentTimeMillis(),
3133                        UsageStats.Event.MOVE_TO_FOREGROUND);
3134            }
3135            synchronized (stats) {
3136                stats.noteActivityResumedLocked(component.app.uid);
3137            }
3138        } else {
3139            if (mUsageStatsService != null) {
3140                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3141                        System.currentTimeMillis(),
3142                        UsageStats.Event.MOVE_TO_BACKGROUND);
3143            }
3144            synchronized (stats) {
3145                stats.noteActivityPausedLocked(component.app.uid);
3146            }
3147        }
3148    }
3149
3150    Intent getHomeIntent() {
3151        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3152        intent.setComponent(mTopComponent);
3153        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3154            intent.addCategory(Intent.CATEGORY_HOME);
3155        }
3156        return intent;
3157    }
3158
3159    boolean startHomeActivityLocked(int userId) {
3160        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3161                && mTopAction == null) {
3162            // We are running in factory test mode, but unable to find
3163            // the factory test app, so just sit around displaying the
3164            // error message and don't try to start anything.
3165            return false;
3166        }
3167        Intent intent = getHomeIntent();
3168        ActivityInfo aInfo =
3169            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3170        if (aInfo != null) {
3171            intent.setComponent(new ComponentName(
3172                    aInfo.applicationInfo.packageName, aInfo.name));
3173            // Don't do this if the home app is currently being
3174            // instrumented.
3175            aInfo = new ActivityInfo(aInfo);
3176            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3177            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3178                    aInfo.applicationInfo.uid, true);
3179            if (app == null || app.instrumentationClass == null) {
3180                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3181                mStackSupervisor.startHomeActivity(intent, aInfo);
3182            }
3183        }
3184
3185        return true;
3186    }
3187
3188    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3189        ActivityInfo ai = null;
3190        ComponentName comp = intent.getComponent();
3191        try {
3192            if (comp != null) {
3193                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3194            } else {
3195                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3196                        intent,
3197                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3198                            flags, userId);
3199
3200                if (info != null) {
3201                    ai = info.activityInfo;
3202                }
3203            }
3204        } catch (RemoteException e) {
3205            // ignore
3206        }
3207
3208        return ai;
3209    }
3210
3211    /**
3212     * Starts the "new version setup screen" if appropriate.
3213     */
3214    void startSetupActivityLocked() {
3215        // Only do this once per boot.
3216        if (mCheckedForSetup) {
3217            return;
3218        }
3219
3220        // We will show this screen if the current one is a different
3221        // version than the last one shown, and we are not running in
3222        // low-level factory test mode.
3223        final ContentResolver resolver = mContext.getContentResolver();
3224        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3225                Settings.Global.getInt(resolver,
3226                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3227            mCheckedForSetup = true;
3228
3229            // See if we should be showing the platform update setup UI.
3230            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3231            List<ResolveInfo> ris = mContext.getPackageManager()
3232                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3233
3234            // We don't allow third party apps to replace this.
3235            ResolveInfo ri = null;
3236            for (int i=0; ris != null && i<ris.size(); i++) {
3237                if ((ris.get(i).activityInfo.applicationInfo.flags
3238                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3239                    ri = ris.get(i);
3240                    break;
3241                }
3242            }
3243
3244            if (ri != null) {
3245                String vers = ri.activityInfo.metaData != null
3246                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3247                        : null;
3248                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3249                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3250                            Intent.METADATA_SETUP_VERSION);
3251                }
3252                String lastVers = Settings.Secure.getString(
3253                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3254                if (vers != null && !vers.equals(lastVers)) {
3255                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3256                    intent.setComponent(new ComponentName(
3257                            ri.activityInfo.packageName, ri.activityInfo.name));
3258                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3259                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null);
3260                }
3261            }
3262        }
3263    }
3264
3265    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3266        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3267    }
3268
3269    void enforceNotIsolatedCaller(String caller) {
3270        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3271            throw new SecurityException("Isolated process not allowed to call " + caller);
3272        }
3273    }
3274
3275    @Override
3276    public int getFrontActivityScreenCompatMode() {
3277        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3278        synchronized (this) {
3279            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3280        }
3281    }
3282
3283    @Override
3284    public void setFrontActivityScreenCompatMode(int mode) {
3285        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3286                "setFrontActivityScreenCompatMode");
3287        synchronized (this) {
3288            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3289        }
3290    }
3291
3292    @Override
3293    public int getPackageScreenCompatMode(String packageName) {
3294        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3295        synchronized (this) {
3296            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3297        }
3298    }
3299
3300    @Override
3301    public void setPackageScreenCompatMode(String packageName, int mode) {
3302        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3303                "setPackageScreenCompatMode");
3304        synchronized (this) {
3305            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3306        }
3307    }
3308
3309    @Override
3310    public boolean getPackageAskScreenCompat(String packageName) {
3311        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3312        synchronized (this) {
3313            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3314        }
3315    }
3316
3317    @Override
3318    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3319        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3320                "setPackageAskScreenCompat");
3321        synchronized (this) {
3322            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3323        }
3324    }
3325
3326    private void dispatchProcessesChanged() {
3327        int N;
3328        synchronized (this) {
3329            N = mPendingProcessChanges.size();
3330            if (mActiveProcessChanges.length < N) {
3331                mActiveProcessChanges = new ProcessChangeItem[N];
3332            }
3333            mPendingProcessChanges.toArray(mActiveProcessChanges);
3334            mAvailProcessChanges.addAll(mPendingProcessChanges);
3335            mPendingProcessChanges.clear();
3336            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3337        }
3338
3339        int i = mProcessObservers.beginBroadcast();
3340        while (i > 0) {
3341            i--;
3342            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3343            if (observer != null) {
3344                try {
3345                    for (int j=0; j<N; j++) {
3346                        ProcessChangeItem item = mActiveProcessChanges[j];
3347                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3348                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3349                                    + item.pid + " uid=" + item.uid + ": "
3350                                    + item.foregroundActivities);
3351                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3352                                    item.foregroundActivities);
3353                        }
3354                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3355                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3356                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3357                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3358                        }
3359                    }
3360                } catch (RemoteException e) {
3361                }
3362            }
3363        }
3364        mProcessObservers.finishBroadcast();
3365    }
3366
3367    private void dispatchProcessDied(int pid, int uid) {
3368        int i = mProcessObservers.beginBroadcast();
3369        while (i > 0) {
3370            i--;
3371            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3372            if (observer != null) {
3373                try {
3374                    observer.onProcessDied(pid, uid);
3375                } catch (RemoteException e) {
3376                }
3377            }
3378        }
3379        mProcessObservers.finishBroadcast();
3380    }
3381
3382    @Override
3383    public final int startActivity(IApplicationThread caller, String callingPackage,
3384            Intent intent, String resolvedType, IBinder resultTo,
3385            String resultWho, int requestCode, int startFlags,
3386            String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
3387        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3388                resultWho, requestCode,
3389                startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
3390    }
3391
3392    @Override
3393    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3394            Intent intent, String resolvedType, IBinder resultTo,
3395            String resultWho, int requestCode, int startFlags,
3396            String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
3397        enforceNotIsolatedCaller("startActivity");
3398        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3399                false, ALLOW_FULL_ONLY, "startActivity", null);
3400        // TODO: Switch to user app stacks here.
3401        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3402                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3403                null, null, options, userId, null);
3404    }
3405
3406    @Override
3407    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3408            Intent intent, String resolvedType, IBinder resultTo,
3409            String resultWho, int requestCode, int startFlags, String profileFile,
3410            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3411        enforceNotIsolatedCaller("startActivityAndWait");
3412        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3413                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3414        WaitResult res = new WaitResult();
3415        // TODO: Switch to user app stacks here.
3416        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3417                null, null, resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
3418                res, null, options, userId, null);
3419        return res;
3420    }
3421
3422    @Override
3423    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3424            Intent intent, String resolvedType, IBinder resultTo,
3425            String resultWho, int requestCode, int startFlags, Configuration config,
3426            Bundle options, int userId) {
3427        enforceNotIsolatedCaller("startActivityWithConfig");
3428        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3429                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3430        // TODO: Switch to user app stacks here.
3431        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3432                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3433                null, null, null, config, options, userId, null);
3434        return ret;
3435    }
3436
3437    @Override
3438    public int startActivityIntentSender(IApplicationThread caller,
3439            IntentSender intent, Intent fillInIntent, String resolvedType,
3440            IBinder resultTo, String resultWho, int requestCode,
3441            int flagsMask, int flagsValues, Bundle options) {
3442        enforceNotIsolatedCaller("startActivityIntentSender");
3443        // Refuse possible leaked file descriptors
3444        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3445            throw new IllegalArgumentException("File descriptors passed in Intent");
3446        }
3447
3448        IIntentSender sender = intent.getTarget();
3449        if (!(sender instanceof PendingIntentRecord)) {
3450            throw new IllegalArgumentException("Bad PendingIntent object");
3451        }
3452
3453        PendingIntentRecord pir = (PendingIntentRecord)sender;
3454
3455        synchronized (this) {
3456            // If this is coming from the currently resumed activity, it is
3457            // effectively saying that app switches are allowed at this point.
3458            final ActivityStack stack = getFocusedStack();
3459            if (stack.mResumedActivity != null &&
3460                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3461                mAppSwitchesAllowedTime = 0;
3462            }
3463        }
3464        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3465                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3466        return ret;
3467    }
3468
3469    @Override
3470    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3471            Intent intent, String resolvedType, IVoiceInteractionSession session,
3472            IVoiceInteractor interactor, int startFlags, String profileFile,
3473            ParcelFileDescriptor profileFd, Bundle options, int userId) {
3474        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3475                != PackageManager.PERMISSION_GRANTED) {
3476            String msg = "Permission Denial: startVoiceActivity() from pid="
3477                    + Binder.getCallingPid()
3478                    + ", uid=" + Binder.getCallingUid()
3479                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3480            Slog.w(TAG, msg);
3481            throw new SecurityException(msg);
3482        }
3483        if (session == null || interactor == null) {
3484            throw new NullPointerException("null session or interactor");
3485        }
3486        userId = handleIncomingUser(callingPid, callingUid, userId,
3487                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3488        // TODO: Switch to user app stacks here.
3489        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3490                resolvedType, session, interactor, null, null, 0, startFlags,
3491                profileFile, profileFd, null, null, options, userId, null);
3492    }
3493
3494    @Override
3495    public boolean startNextMatchingActivity(IBinder callingActivity,
3496            Intent intent, Bundle options) {
3497        // Refuse possible leaked file descriptors
3498        if (intent != null && intent.hasFileDescriptors() == true) {
3499            throw new IllegalArgumentException("File descriptors passed in Intent");
3500        }
3501
3502        synchronized (this) {
3503            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3504            if (r == null) {
3505                ActivityOptions.abort(options);
3506                return false;
3507            }
3508            if (r.app == null || r.app.thread == null) {
3509                // The caller is not running...  d'oh!
3510                ActivityOptions.abort(options);
3511                return false;
3512            }
3513            intent = new Intent(intent);
3514            // The caller is not allowed to change the data.
3515            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3516            // And we are resetting to find the next component...
3517            intent.setComponent(null);
3518
3519            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3520
3521            ActivityInfo aInfo = null;
3522            try {
3523                List<ResolveInfo> resolves =
3524                    AppGlobals.getPackageManager().queryIntentActivities(
3525                            intent, r.resolvedType,
3526                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3527                            UserHandle.getCallingUserId());
3528
3529                // Look for the original activity in the list...
3530                final int N = resolves != null ? resolves.size() : 0;
3531                for (int i=0; i<N; i++) {
3532                    ResolveInfo rInfo = resolves.get(i);
3533                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3534                            && rInfo.activityInfo.name.equals(r.info.name)) {
3535                        // We found the current one...  the next matching is
3536                        // after it.
3537                        i++;
3538                        if (i<N) {
3539                            aInfo = resolves.get(i).activityInfo;
3540                        }
3541                        if (debug) {
3542                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3543                                    + "/" + r.info.name);
3544                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3545                                    + "/" + aInfo.name);
3546                        }
3547                        break;
3548                    }
3549                }
3550            } catch (RemoteException e) {
3551            }
3552
3553            if (aInfo == null) {
3554                // Nobody who is next!
3555                ActivityOptions.abort(options);
3556                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3557                return false;
3558            }
3559
3560            intent.setComponent(new ComponentName(
3561                    aInfo.applicationInfo.packageName, aInfo.name));
3562            intent.setFlags(intent.getFlags()&~(
3563                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3564                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3565                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3566                    Intent.FLAG_ACTIVITY_NEW_TASK));
3567
3568            // Okay now we need to start the new activity, replacing the
3569            // currently running activity.  This is a little tricky because
3570            // we want to start the new one as if the current one is finished,
3571            // but not finish the current one first so that there is no flicker.
3572            // And thus...
3573            final boolean wasFinishing = r.finishing;
3574            r.finishing = true;
3575
3576            // Propagate reply information over to the new activity.
3577            final ActivityRecord resultTo = r.resultTo;
3578            final String resultWho = r.resultWho;
3579            final int requestCode = r.requestCode;
3580            r.resultTo = null;
3581            if (resultTo != null) {
3582                resultTo.removeResultsLocked(r, resultWho, requestCode);
3583            }
3584
3585            final long origId = Binder.clearCallingIdentity();
3586            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3587                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3588                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3589                    options, false, null, null);
3590            Binder.restoreCallingIdentity(origId);
3591
3592            r.finishing = wasFinishing;
3593            if (res != ActivityManager.START_SUCCESS) {
3594                return false;
3595            }
3596            return true;
3597        }
3598    }
3599
3600    @Override
3601    public final int startActivityFromRecents(int taskId, Bundle options) {
3602        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3603            String msg = "Permission Denial: startActivityFromRecents called without " +
3604                    START_TASKS_FROM_RECENTS;
3605            Slog.w(TAG, msg);
3606            throw new SecurityException(msg);
3607        }
3608        final int callingUid;
3609        final String callingPackage;
3610        final Intent intent;
3611        final int userId;
3612        synchronized (this) {
3613            final TaskRecord task = recentTaskForIdLocked(taskId);
3614            if (task == null) {
3615                throw new ActivityNotFoundException("Task " + taskId + " not found.");
3616            }
3617            callingUid = task.mCallingUid;
3618            callingPackage = task.mCallingPackage;
3619            intent = task.intent;
3620            userId = task.userId;
3621        }
3622        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3623                options, userId, null);
3624    }
3625
3626    final int startActivityInPackage(int uid, String callingPackage,
3627            Intent intent, String resolvedType, IBinder resultTo,
3628            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3629                    IActivityContainer container) {
3630
3631        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3632                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3633
3634        // TODO: Switch to user app stacks here.
3635        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
3636                null, null, resultTo, resultWho, requestCode, startFlags,
3637                null, null, null, null, options, userId, container);
3638        return ret;
3639    }
3640
3641    @Override
3642    public final int startActivities(IApplicationThread caller, String callingPackage,
3643            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3644            int userId) {
3645        enforceNotIsolatedCaller("startActivities");
3646        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3647                false, ALLOW_FULL_ONLY, "startActivity", null);
3648        // TODO: Switch to user app stacks here.
3649        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3650                resolvedTypes, resultTo, options, userId);
3651        return ret;
3652    }
3653
3654    final int startActivitiesInPackage(int uid, String callingPackage,
3655            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3656            Bundle options, int userId) {
3657
3658        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3659                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3660        // TODO: Switch to user app stacks here.
3661        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3662                resultTo, options, userId);
3663        return ret;
3664    }
3665
3666    //explicitly remove thd old information in mRecentTasks when removing existing user.
3667    private void removeRecentTasksForUser(int userId) {
3668        if(userId <= 0) {
3669            Slog.i(TAG, "Can't remove recent task on user " + userId);
3670            return;
3671        }
3672
3673        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3674            TaskRecord tr = mRecentTasks.get(i);
3675            if (tr.userId == userId) {
3676                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3677                        + " when finishing user" + userId);
3678                tr.disposeThumbnail();
3679                mRecentTasks.remove(i);
3680            }
3681        }
3682
3683        // Remove tasks from persistent storage.
3684        mTaskPersister.wakeup(null, true);
3685    }
3686
3687    final void addRecentTaskLocked(TaskRecord task) {
3688        int N = mRecentTasks.size();
3689        // Quick case: check if the top-most recent task is the same.
3690        if (N > 0 && mRecentTasks.get(0) == task) {
3691            return;
3692        }
3693        // Another quick case: never add voice sessions.
3694        if (task.voiceSession != null) {
3695            return;
3696        }
3697        // Remove any existing entries that are the same kind of task.
3698        final Intent intent = task.intent;
3699        final boolean document = intent != null && intent.isDocument();
3700        final ComponentName comp = intent.getComponent();
3701
3702        int maxRecents = task.maxRecents - 1;
3703        for (int i=0; i<N; i++) {
3704            final TaskRecord tr = mRecentTasks.get(i);
3705            if (task != tr) {
3706                if (task.userId != tr.userId) {
3707                    continue;
3708                }
3709                if (i > MAX_RECENT_BITMAPS) {
3710                    tr.freeLastThumbnail();
3711                }
3712                final Intent trIntent = tr.intent;
3713                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
3714                    (intent == null || !intent.filterEquals(trIntent))) {
3715                    continue;
3716                }
3717                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
3718                if (document && trIsDocument) {
3719                    // These are the same document activity (not necessarily the same doc).
3720                    if (maxRecents > 0) {
3721                        --maxRecents;
3722                        continue;
3723                    }
3724                    // Hit the maximum number of documents for this task. Fall through
3725                    // and remove this document from recents.
3726                } else if (document || trIsDocument) {
3727                    // Only one of these is a document. Not the droid we're looking for.
3728                    continue;
3729                }
3730            }
3731
3732            // Either task and tr are the same or, their affinities match or their intents match
3733            // and neither of them is a document, or they are documents using the same activity
3734            // and their maxRecents has been reached.
3735            tr.disposeThumbnail();
3736            mRecentTasks.remove(i);
3737            if (task != tr) {
3738                tr.closeRecentsChain();
3739            }
3740            i--;
3741            N--;
3742            if (task.intent == null) {
3743                // If the new recent task we are adding is not fully
3744                // specified, then replace it with the existing recent task.
3745                task = tr;
3746            }
3747            notifyTaskPersisterLocked(tr, false);
3748        }
3749        if (N >= MAX_RECENT_TASKS) {
3750            final TaskRecord tr = mRecentTasks.remove(N - 1);
3751            tr.disposeThumbnail();
3752            tr.closeRecentsChain();
3753        }
3754        mRecentTasks.add(0, task);
3755    }
3756
3757    @Override
3758    public void reportActivityFullyDrawn(IBinder token) {
3759        synchronized (this) {
3760            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3761            if (r == null) {
3762                return;
3763            }
3764            r.reportFullyDrawnLocked();
3765        }
3766    }
3767
3768    @Override
3769    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
3770        synchronized (this) {
3771            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3772            if (r == null) {
3773                return;
3774            }
3775            final long origId = Binder.clearCallingIdentity();
3776            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
3777            Configuration config = mWindowManager.updateOrientationFromAppTokens(
3778                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
3779            if (config != null) {
3780                r.frozenBeforeDestroy = true;
3781                if (!updateConfigurationLocked(config, r, false, false)) {
3782                    mStackSupervisor.resumeTopActivitiesLocked();
3783                }
3784            }
3785            Binder.restoreCallingIdentity(origId);
3786        }
3787    }
3788
3789    @Override
3790    public int getRequestedOrientation(IBinder token) {
3791        synchronized (this) {
3792            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3793            if (r == null) {
3794                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
3795            }
3796            return mWindowManager.getAppOrientation(r.appToken);
3797        }
3798    }
3799
3800    /**
3801     * This is the internal entry point for handling Activity.finish().
3802     *
3803     * @param token The Binder token referencing the Activity we want to finish.
3804     * @param resultCode Result code, if any, from this Activity.
3805     * @param resultData Result data (Intent), if any, from this Activity.
3806     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
3807     *            the root Activity in the task.
3808     *
3809     * @return Returns true if the activity successfully finished, or false if it is still running.
3810     */
3811    @Override
3812    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
3813            boolean finishTask) {
3814        // Refuse possible leaked file descriptors
3815        if (resultData != null && resultData.hasFileDescriptors() == true) {
3816            throw new IllegalArgumentException("File descriptors passed in Intent");
3817        }
3818
3819        synchronized(this) {
3820            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3821            if (r == null) {
3822                return true;
3823            }
3824            // Keep track of the root activity of the task before we finish it
3825            TaskRecord tr = r.task;
3826            ActivityRecord rootR = tr.getRootActivity();
3827            // Do not allow task to finish in Lock Task mode.
3828            if (tr == mStackSupervisor.mLockTaskModeTask) {
3829                if (rootR == r) {
3830                    mStackSupervisor.showLockTaskToast();
3831                    return false;
3832                }
3833            }
3834            if (mController != null) {
3835                // Find the first activity that is not finishing.
3836                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
3837                if (next != null) {
3838                    // ask watcher if this is allowed
3839                    boolean resumeOK = true;
3840                    try {
3841                        resumeOK = mController.activityResuming(next.packageName);
3842                    } catch (RemoteException e) {
3843                        mController = null;
3844                        Watchdog.getInstance().setActivityController(null);
3845                    }
3846
3847                    if (!resumeOK) {
3848                        return false;
3849                    }
3850                }
3851            }
3852            final long origId = Binder.clearCallingIdentity();
3853            try {
3854                boolean res;
3855                if (finishTask && r == rootR) {
3856                    // If requested, remove the task that is associated to this activity only if it
3857                    // was the root activity in the task.  The result code and data is ignored because
3858                    // we don't support returning them across task boundaries.
3859                    res = removeTaskByIdLocked(tr.taskId, 0);
3860                } else {
3861                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
3862                            resultData, "app-request", true);
3863                }
3864                return res;
3865            } finally {
3866                Binder.restoreCallingIdentity(origId);
3867            }
3868        }
3869    }
3870
3871    @Override
3872    public final void finishHeavyWeightApp() {
3873        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3874                != PackageManager.PERMISSION_GRANTED) {
3875            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
3876                    + Binder.getCallingPid()
3877                    + ", uid=" + Binder.getCallingUid()
3878                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3879            Slog.w(TAG, msg);
3880            throw new SecurityException(msg);
3881        }
3882
3883        synchronized(this) {
3884            if (mHeavyWeightProcess == null) {
3885                return;
3886            }
3887
3888            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
3889                    mHeavyWeightProcess.activities);
3890            for (int i=0; i<activities.size(); i++) {
3891                ActivityRecord r = activities.get(i);
3892                if (!r.finishing) {
3893                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
3894                            null, "finish-heavy", true);
3895                }
3896            }
3897
3898            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3899                    mHeavyWeightProcess.userId, 0));
3900            mHeavyWeightProcess = null;
3901        }
3902    }
3903
3904    @Override
3905    public void crashApplication(int uid, int initialPid, String packageName,
3906            String message) {
3907        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3908                != PackageManager.PERMISSION_GRANTED) {
3909            String msg = "Permission Denial: crashApplication() from pid="
3910                    + Binder.getCallingPid()
3911                    + ", uid=" + Binder.getCallingUid()
3912                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
3913            Slog.w(TAG, msg);
3914            throw new SecurityException(msg);
3915        }
3916
3917        synchronized(this) {
3918            ProcessRecord proc = null;
3919
3920            // Figure out which process to kill.  We don't trust that initialPid
3921            // still has any relation to current pids, so must scan through the
3922            // list.
3923            synchronized (mPidsSelfLocked) {
3924                for (int i=0; i<mPidsSelfLocked.size(); i++) {
3925                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
3926                    if (p.uid != uid) {
3927                        continue;
3928                    }
3929                    if (p.pid == initialPid) {
3930                        proc = p;
3931                        break;
3932                    }
3933                    if (p.pkgList.containsKey(packageName)) {
3934                        proc = p;
3935                    }
3936                }
3937            }
3938
3939            if (proc == null) {
3940                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
3941                        + " initialPid=" + initialPid
3942                        + " packageName=" + packageName);
3943                return;
3944            }
3945
3946            if (proc.thread != null) {
3947                if (proc.pid == Process.myPid()) {
3948                    Log.w(TAG, "crashApplication: trying to crash self!");
3949                    return;
3950                }
3951                long ident = Binder.clearCallingIdentity();
3952                try {
3953                    proc.thread.scheduleCrash(message);
3954                } catch (RemoteException e) {
3955                }
3956                Binder.restoreCallingIdentity(ident);
3957            }
3958        }
3959    }
3960
3961    @Override
3962    public final void finishSubActivity(IBinder token, String resultWho,
3963            int requestCode) {
3964        synchronized(this) {
3965            final long origId = Binder.clearCallingIdentity();
3966            ActivityRecord r = ActivityRecord.isInStackLocked(token);
3967            if (r != null) {
3968                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
3969            }
3970            Binder.restoreCallingIdentity(origId);
3971        }
3972    }
3973
3974    @Override
3975    public boolean finishActivityAffinity(IBinder token) {
3976        synchronized(this) {
3977            final long origId = Binder.clearCallingIdentity();
3978            try {
3979                ActivityRecord r = ActivityRecord.isInStackLocked(token);
3980
3981                ActivityRecord rootR = r.task.getRootActivity();
3982                // Do not allow task to finish in Lock Task mode.
3983                if (r.task == mStackSupervisor.mLockTaskModeTask) {
3984                    if (rootR == r) {
3985                        mStackSupervisor.showLockTaskToast();
3986                        return false;
3987                    }
3988                }
3989                boolean res = false;
3990                if (r != null) {
3991                    res = r.task.stack.finishActivityAffinityLocked(r);
3992                }
3993                return res;
3994            } finally {
3995                Binder.restoreCallingIdentity(origId);
3996            }
3997        }
3998    }
3999
4000    @Override
4001    public void finishVoiceTask(IVoiceInteractionSession session) {
4002        synchronized(this) {
4003            final long origId = Binder.clearCallingIdentity();
4004            try {
4005                mStackSupervisor.finishVoiceTask(session);
4006            } finally {
4007                Binder.restoreCallingIdentity(origId);
4008            }
4009        }
4010
4011    }
4012
4013    @Override
4014    public boolean willActivityBeVisible(IBinder token) {
4015        synchronized(this) {
4016            ActivityStack stack = ActivityRecord.getStackLocked(token);
4017            if (stack != null) {
4018                return stack.willActivityBeVisibleLocked(token);
4019            }
4020            return false;
4021        }
4022    }
4023
4024    @Override
4025    public void overridePendingTransition(IBinder token, String packageName,
4026            int enterAnim, int exitAnim) {
4027        synchronized(this) {
4028            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4029            if (self == null) {
4030                return;
4031            }
4032
4033            final long origId = Binder.clearCallingIdentity();
4034
4035            if (self.state == ActivityState.RESUMED
4036                    || self.state == ActivityState.PAUSING) {
4037                mWindowManager.overridePendingAppTransition(packageName,
4038                        enterAnim, exitAnim, null);
4039            }
4040
4041            Binder.restoreCallingIdentity(origId);
4042        }
4043    }
4044
4045    /**
4046     * Main function for removing an existing process from the activity manager
4047     * as a result of that process going away.  Clears out all connections
4048     * to the process.
4049     */
4050    private final void handleAppDiedLocked(ProcessRecord app,
4051            boolean restarting, boolean allowRestart) {
4052        int pid = app.pid;
4053        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4054        if (!restarting) {
4055            removeLruProcessLocked(app);
4056            if (pid > 0) {
4057                ProcessList.remove(pid);
4058            }
4059        }
4060
4061        if (mProfileProc == app) {
4062            clearProfilerLocked();
4063        }
4064
4065        // Remove this application's activities from active lists.
4066        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4067
4068        app.activities.clear();
4069
4070        if (app.instrumentationClass != null) {
4071            Slog.w(TAG, "Crash of app " + app.processName
4072                  + " running instrumentation " + app.instrumentationClass);
4073            Bundle info = new Bundle();
4074            info.putString("shortMsg", "Process crashed.");
4075            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4076        }
4077
4078        if (!restarting) {
4079            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4080                // If there was nothing to resume, and we are not already
4081                // restarting this process, but there is a visible activity that
4082                // is hosted by the process...  then make sure all visible
4083                // activities are running, taking care of restarting this
4084                // process.
4085                if (hasVisibleActivities) {
4086                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4087                }
4088            }
4089        }
4090    }
4091
4092    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4093        IBinder threadBinder = thread.asBinder();
4094        // Find the application record.
4095        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4096            ProcessRecord rec = mLruProcesses.get(i);
4097            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4098                return i;
4099            }
4100        }
4101        return -1;
4102    }
4103
4104    final ProcessRecord getRecordForAppLocked(
4105            IApplicationThread thread) {
4106        if (thread == null) {
4107            return null;
4108        }
4109
4110        int appIndex = getLRURecordIndexForAppLocked(thread);
4111        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4112    }
4113
4114    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4115        // If there are no longer any background processes running,
4116        // and the app that died was not running instrumentation,
4117        // then tell everyone we are now low on memory.
4118        boolean haveBg = false;
4119        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4120            ProcessRecord rec = mLruProcesses.get(i);
4121            if (rec.thread != null
4122                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4123                haveBg = true;
4124                break;
4125            }
4126        }
4127
4128        if (!haveBg) {
4129            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4130            if (doReport) {
4131                long now = SystemClock.uptimeMillis();
4132                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4133                    doReport = false;
4134                } else {
4135                    mLastMemUsageReportTime = now;
4136                }
4137            }
4138            final ArrayList<ProcessMemInfo> memInfos
4139                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4140            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4141            long now = SystemClock.uptimeMillis();
4142            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4143                ProcessRecord rec = mLruProcesses.get(i);
4144                if (rec == dyingProc || rec.thread == null) {
4145                    continue;
4146                }
4147                if (doReport) {
4148                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4149                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4150                }
4151                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4152                    // The low memory report is overriding any current
4153                    // state for a GC request.  Make sure to do
4154                    // heavy/important/visible/foreground processes first.
4155                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4156                        rec.lastRequestedGc = 0;
4157                    } else {
4158                        rec.lastRequestedGc = rec.lastLowMemory;
4159                    }
4160                    rec.reportLowMemory = true;
4161                    rec.lastLowMemory = now;
4162                    mProcessesToGc.remove(rec);
4163                    addProcessToGcListLocked(rec);
4164                }
4165            }
4166            if (doReport) {
4167                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4168                mHandler.sendMessage(msg);
4169            }
4170            scheduleAppGcsLocked();
4171        }
4172    }
4173
4174    final void appDiedLocked(ProcessRecord app, int pid,
4175            IApplicationThread thread) {
4176
4177        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4178        synchronized (stats) {
4179            stats.noteProcessDiedLocked(app.info.uid, pid);
4180        }
4181
4182        Process.killProcessGroup(app.info.uid, pid);
4183
4184        // Clean up already done if the process has been re-started.
4185        if (app.pid == pid && app.thread != null &&
4186                app.thread.asBinder() == thread.asBinder()) {
4187            boolean doLowMem = app.instrumentationClass == null;
4188            boolean doOomAdj = doLowMem;
4189            if (!app.killedByAm) {
4190                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4191                        + ") has died.");
4192                mAllowLowerMemLevel = true;
4193            } else {
4194                // Note that we always want to do oom adj to update our state with the
4195                // new number of procs.
4196                mAllowLowerMemLevel = false;
4197                doLowMem = false;
4198            }
4199            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4200            if (DEBUG_CLEANUP) Slog.v(
4201                TAG, "Dying app: " + app + ", pid: " + pid
4202                + ", thread: " + thread.asBinder());
4203            handleAppDiedLocked(app, false, true);
4204
4205            if (doOomAdj) {
4206                updateOomAdjLocked();
4207            }
4208            if (doLowMem) {
4209                doLowMemReportIfNeededLocked(app);
4210            }
4211        } else if (app.pid != pid) {
4212            // A new process has already been started.
4213            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4214                    + ") has died and restarted (pid " + app.pid + ").");
4215            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4216        } else if (DEBUG_PROCESSES) {
4217            Slog.d(TAG, "Received spurious death notification for thread "
4218                    + thread.asBinder());
4219        }
4220    }
4221
4222    /**
4223     * If a stack trace dump file is configured, dump process stack traces.
4224     * @param clearTraces causes the dump file to be erased prior to the new
4225     *    traces being written, if true; when false, the new traces will be
4226     *    appended to any existing file content.
4227     * @param firstPids of dalvik VM processes to dump stack traces for first
4228     * @param lastPids of dalvik VM processes to dump stack traces for last
4229     * @param nativeProcs optional list of native process names to dump stack crawls
4230     * @return file containing stack traces, or null if no dump file is configured
4231     */
4232    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4233            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4234        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4235        if (tracesPath == null || tracesPath.length() == 0) {
4236            return null;
4237        }
4238
4239        File tracesFile = new File(tracesPath);
4240        try {
4241            File tracesDir = tracesFile.getParentFile();
4242            if (!tracesDir.exists()) {
4243                tracesFile.mkdirs();
4244                if (!SELinux.restorecon(tracesDir)) {
4245                    return null;
4246                }
4247            }
4248            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4249
4250            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4251            tracesFile.createNewFile();
4252            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4253        } catch (IOException e) {
4254            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4255            return null;
4256        }
4257
4258        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4259        return tracesFile;
4260    }
4261
4262    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4263            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4264        // Use a FileObserver to detect when traces finish writing.
4265        // The order of traces is considered important to maintain for legibility.
4266        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4267            @Override
4268            public synchronized void onEvent(int event, String path) { notify(); }
4269        };
4270
4271        try {
4272            observer.startWatching();
4273
4274            // First collect all of the stacks of the most important pids.
4275            if (firstPids != null) {
4276                try {
4277                    int num = firstPids.size();
4278                    for (int i = 0; i < num; i++) {
4279                        synchronized (observer) {
4280                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4281                            observer.wait(200);  // Wait for write-close, give up after 200msec
4282                        }
4283                    }
4284                } catch (InterruptedException e) {
4285                    Log.wtf(TAG, e);
4286                }
4287            }
4288
4289            // Next collect the stacks of the native pids
4290            if (nativeProcs != null) {
4291                int[] pids = Process.getPidsForCommands(nativeProcs);
4292                if (pids != null) {
4293                    for (int pid : pids) {
4294                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4295                    }
4296                }
4297            }
4298
4299            // Lastly, measure CPU usage.
4300            if (processCpuTracker != null) {
4301                processCpuTracker.init();
4302                System.gc();
4303                processCpuTracker.update();
4304                try {
4305                    synchronized (processCpuTracker) {
4306                        processCpuTracker.wait(500); // measure over 1/2 second.
4307                    }
4308                } catch (InterruptedException e) {
4309                }
4310                processCpuTracker.update();
4311
4312                // We'll take the stack crawls of just the top apps using CPU.
4313                final int N = processCpuTracker.countWorkingStats();
4314                int numProcs = 0;
4315                for (int i=0; i<N && numProcs<5; i++) {
4316                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4317                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4318                        numProcs++;
4319                        try {
4320                            synchronized (observer) {
4321                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4322                                observer.wait(200);  // Wait for write-close, give up after 200msec
4323                            }
4324                        } catch (InterruptedException e) {
4325                            Log.wtf(TAG, e);
4326                        }
4327
4328                    }
4329                }
4330            }
4331        } finally {
4332            observer.stopWatching();
4333        }
4334    }
4335
4336    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4337        if (true || IS_USER_BUILD) {
4338            return;
4339        }
4340        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4341        if (tracesPath == null || tracesPath.length() == 0) {
4342            return;
4343        }
4344
4345        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4346        StrictMode.allowThreadDiskWrites();
4347        try {
4348            final File tracesFile = new File(tracesPath);
4349            final File tracesDir = tracesFile.getParentFile();
4350            final File tracesTmp = new File(tracesDir, "__tmp__");
4351            try {
4352                if (!tracesDir.exists()) {
4353                    tracesFile.mkdirs();
4354                    if (!SELinux.restorecon(tracesDir.getPath())) {
4355                        return;
4356                    }
4357                }
4358                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4359
4360                if (tracesFile.exists()) {
4361                    tracesTmp.delete();
4362                    tracesFile.renameTo(tracesTmp);
4363                }
4364                StringBuilder sb = new StringBuilder();
4365                Time tobj = new Time();
4366                tobj.set(System.currentTimeMillis());
4367                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4368                sb.append(": ");
4369                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4370                sb.append(" since ");
4371                sb.append(msg);
4372                FileOutputStream fos = new FileOutputStream(tracesFile);
4373                fos.write(sb.toString().getBytes());
4374                if (app == null) {
4375                    fos.write("\n*** No application process!".getBytes());
4376                }
4377                fos.close();
4378                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4379            } catch (IOException e) {
4380                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4381                return;
4382            }
4383
4384            if (app != null) {
4385                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4386                firstPids.add(app.pid);
4387                dumpStackTraces(tracesPath, firstPids, null, null, null);
4388            }
4389
4390            File lastTracesFile = null;
4391            File curTracesFile = null;
4392            for (int i=9; i>=0; i--) {
4393                String name = String.format(Locale.US, "slow%02d.txt", i);
4394                curTracesFile = new File(tracesDir, name);
4395                if (curTracesFile.exists()) {
4396                    if (lastTracesFile != null) {
4397                        curTracesFile.renameTo(lastTracesFile);
4398                    } else {
4399                        curTracesFile.delete();
4400                    }
4401                }
4402                lastTracesFile = curTracesFile;
4403            }
4404            tracesFile.renameTo(curTracesFile);
4405            if (tracesTmp.exists()) {
4406                tracesTmp.renameTo(tracesFile);
4407            }
4408        } finally {
4409            StrictMode.setThreadPolicy(oldPolicy);
4410        }
4411    }
4412
4413    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4414            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4415        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4416        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4417
4418        if (mController != null) {
4419            try {
4420                // 0 == continue, -1 = kill process immediately
4421                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4422                if (res < 0 && app.pid != MY_PID) {
4423                    Process.killProcess(app.pid);
4424                    Process.killProcessGroup(app.info.uid, app.pid);
4425                }
4426            } catch (RemoteException e) {
4427                mController = null;
4428                Watchdog.getInstance().setActivityController(null);
4429            }
4430        }
4431
4432        long anrTime = SystemClock.uptimeMillis();
4433        if (MONITOR_CPU_USAGE) {
4434            updateCpuStatsNow();
4435        }
4436
4437        synchronized (this) {
4438            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4439            if (mShuttingDown) {
4440                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4441                return;
4442            } else if (app.notResponding) {
4443                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4444                return;
4445            } else if (app.crashing) {
4446                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4447                return;
4448            }
4449
4450            // In case we come through here for the same app before completing
4451            // this one, mark as anring now so we will bail out.
4452            app.notResponding = true;
4453
4454            // Log the ANR to the event log.
4455            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4456                    app.processName, app.info.flags, annotation);
4457
4458            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4459            firstPids.add(app.pid);
4460
4461            int parentPid = app.pid;
4462            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4463            if (parentPid != app.pid) firstPids.add(parentPid);
4464
4465            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
4466
4467            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
4468                ProcessRecord r = mLruProcesses.get(i);
4469                if (r != null && r.thread != null) {
4470                    int pid = r.pid;
4471                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
4472                        if (r.persistent) {
4473                            firstPids.add(pid);
4474                        } else {
4475                            lastPids.put(pid, Boolean.TRUE);
4476                        }
4477                    }
4478                }
4479            }
4480        }
4481
4482        // Log the ANR to the main log.
4483        StringBuilder info = new StringBuilder();
4484        info.setLength(0);
4485        info.append("ANR in ").append(app.processName);
4486        if (activity != null && activity.shortComponentName != null) {
4487            info.append(" (").append(activity.shortComponentName).append(")");
4488        }
4489        info.append("\n");
4490        info.append("PID: ").append(app.pid).append("\n");
4491        if (annotation != null) {
4492            info.append("Reason: ").append(annotation).append("\n");
4493        }
4494        if (parent != null && parent != activity) {
4495            info.append("Parent: ").append(parent.shortComponentName).append("\n");
4496        }
4497
4498        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
4499
4500        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
4501                NATIVE_STACKS_OF_INTEREST);
4502
4503        String cpuInfo = null;
4504        if (MONITOR_CPU_USAGE) {
4505            updateCpuStatsNow();
4506            synchronized (mProcessCpuThread) {
4507                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
4508            }
4509            info.append(processCpuTracker.printCurrentLoad());
4510            info.append(cpuInfo);
4511        }
4512
4513        info.append(processCpuTracker.printCurrentState(anrTime));
4514
4515        Slog.e(TAG, info.toString());
4516        if (tracesFile == null) {
4517            // There is no trace file, so dump (only) the alleged culprit's threads to the log
4518            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
4519        }
4520
4521        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
4522                cpuInfo, tracesFile, null);
4523
4524        if (mController != null) {
4525            try {
4526                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
4527                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
4528                if (res != 0) {
4529                    if (res < 0 && app.pid != MY_PID) {
4530                        Process.killProcess(app.pid);
4531                        Process.killProcessGroup(app.info.uid, app.pid);
4532                    } else {
4533                        synchronized (this) {
4534                            mServices.scheduleServiceTimeoutLocked(app);
4535                        }
4536                    }
4537                    return;
4538                }
4539            } catch (RemoteException e) {
4540                mController = null;
4541                Watchdog.getInstance().setActivityController(null);
4542            }
4543        }
4544
4545        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
4546        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
4547                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
4548
4549        synchronized (this) {
4550            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
4551                killUnneededProcessLocked(app, "background ANR");
4552                return;
4553            }
4554
4555            // Set the app's notResponding state, and look up the errorReportReceiver
4556            makeAppNotRespondingLocked(app,
4557                    activity != null ? activity.shortComponentName : null,
4558                    annotation != null ? "ANR " + annotation : "ANR",
4559                    info.toString());
4560
4561            // Bring up the infamous App Not Responding dialog
4562            Message msg = Message.obtain();
4563            HashMap<String, Object> map = new HashMap<String, Object>();
4564            msg.what = SHOW_NOT_RESPONDING_MSG;
4565            msg.obj = map;
4566            msg.arg1 = aboveSystem ? 1 : 0;
4567            map.put("app", app);
4568            if (activity != null) {
4569                map.put("activity", activity);
4570            }
4571
4572            mHandler.sendMessage(msg);
4573        }
4574    }
4575
4576    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
4577        if (!mLaunchWarningShown) {
4578            mLaunchWarningShown = true;
4579            mHandler.post(new Runnable() {
4580                @Override
4581                public void run() {
4582                    synchronized (ActivityManagerService.this) {
4583                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
4584                        d.show();
4585                        mHandler.postDelayed(new Runnable() {
4586                            @Override
4587                            public void run() {
4588                                synchronized (ActivityManagerService.this) {
4589                                    d.dismiss();
4590                                    mLaunchWarningShown = false;
4591                                }
4592                            }
4593                        }, 4000);
4594                    }
4595                }
4596            });
4597        }
4598    }
4599
4600    @Override
4601    public boolean clearApplicationUserData(final String packageName,
4602            final IPackageDataObserver observer, int userId) {
4603        enforceNotIsolatedCaller("clearApplicationUserData");
4604        int uid = Binder.getCallingUid();
4605        int pid = Binder.getCallingPid();
4606        userId = handleIncomingUser(pid, uid,
4607                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
4608        long callingId = Binder.clearCallingIdentity();
4609        try {
4610            IPackageManager pm = AppGlobals.getPackageManager();
4611            int pkgUid = -1;
4612            synchronized(this) {
4613                try {
4614                    pkgUid = pm.getPackageUid(packageName, userId);
4615                } catch (RemoteException e) {
4616                }
4617                if (pkgUid == -1) {
4618                    Slog.w(TAG, "Invalid packageName: " + packageName);
4619                    if (observer != null) {
4620                        try {
4621                            observer.onRemoveCompleted(packageName, false);
4622                        } catch (RemoteException e) {
4623                            Slog.i(TAG, "Observer no longer exists.");
4624                        }
4625                    }
4626                    return false;
4627                }
4628                if (uid == pkgUid || checkComponentPermission(
4629                        android.Manifest.permission.CLEAR_APP_USER_DATA,
4630                        pid, uid, -1, true)
4631                        == PackageManager.PERMISSION_GRANTED) {
4632                    forceStopPackageLocked(packageName, pkgUid, "clear data");
4633                } else {
4634                    throw new SecurityException("PID " + pid + " does not have permission "
4635                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
4636                                    + " of package " + packageName);
4637                }
4638            }
4639
4640            try {
4641                // Clear application user data
4642                pm.clearApplicationUserData(packageName, observer, userId);
4643
4644                // Remove all permissions granted from/to this package
4645                removeUriPermissionsForPackageLocked(packageName, userId, true);
4646
4647                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
4648                        Uri.fromParts("package", packageName, null));
4649                intent.putExtra(Intent.EXTRA_UID, pkgUid);
4650                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
4651                        null, null, 0, null, null, null, false, false, userId);
4652            } catch (RemoteException e) {
4653            }
4654        } finally {
4655            Binder.restoreCallingIdentity(callingId);
4656        }
4657        return true;
4658    }
4659
4660    @Override
4661    public void killBackgroundProcesses(final String packageName, int userId) {
4662        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4663                != PackageManager.PERMISSION_GRANTED &&
4664                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
4665                        != PackageManager.PERMISSION_GRANTED) {
4666            String msg = "Permission Denial: killBackgroundProcesses() from pid="
4667                    + Binder.getCallingPid()
4668                    + ", uid=" + Binder.getCallingUid()
4669                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4670            Slog.w(TAG, msg);
4671            throw new SecurityException(msg);
4672        }
4673
4674        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4675                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
4676        long callingId = Binder.clearCallingIdentity();
4677        try {
4678            IPackageManager pm = AppGlobals.getPackageManager();
4679            synchronized(this) {
4680                int appId = -1;
4681                try {
4682                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
4683                } catch (RemoteException e) {
4684                }
4685                if (appId == -1) {
4686                    Slog.w(TAG, "Invalid packageName: " + packageName);
4687                    return;
4688                }
4689                killPackageProcessesLocked(packageName, appId, userId,
4690                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
4691            }
4692        } finally {
4693            Binder.restoreCallingIdentity(callingId);
4694        }
4695    }
4696
4697    @Override
4698    public void killAllBackgroundProcesses() {
4699        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
4700                != PackageManager.PERMISSION_GRANTED) {
4701            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
4702                    + Binder.getCallingPid()
4703                    + ", uid=" + Binder.getCallingUid()
4704                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
4705            Slog.w(TAG, msg);
4706            throw new SecurityException(msg);
4707        }
4708
4709        long callingId = Binder.clearCallingIdentity();
4710        try {
4711            synchronized(this) {
4712                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
4713                final int NP = mProcessNames.getMap().size();
4714                for (int ip=0; ip<NP; ip++) {
4715                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
4716                    final int NA = apps.size();
4717                    for (int ia=0; ia<NA; ia++) {
4718                        ProcessRecord app = apps.valueAt(ia);
4719                        if (app.persistent) {
4720                            // we don't kill persistent processes
4721                            continue;
4722                        }
4723                        if (app.removed) {
4724                            procs.add(app);
4725                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
4726                            app.removed = true;
4727                            procs.add(app);
4728                        }
4729                    }
4730                }
4731
4732                int N = procs.size();
4733                for (int i=0; i<N; i++) {
4734                    removeProcessLocked(procs.get(i), false, true, "kill all background");
4735                }
4736                mAllowLowerMemLevel = true;
4737                updateOomAdjLocked();
4738                doLowMemReportIfNeededLocked(null);
4739            }
4740        } finally {
4741            Binder.restoreCallingIdentity(callingId);
4742        }
4743    }
4744
4745    @Override
4746    public void forceStopPackage(final String packageName, int userId) {
4747        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4748                != PackageManager.PERMISSION_GRANTED) {
4749            String msg = "Permission Denial: forceStopPackage() from pid="
4750                    + Binder.getCallingPid()
4751                    + ", uid=" + Binder.getCallingUid()
4752                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4753            Slog.w(TAG, msg);
4754            throw new SecurityException(msg);
4755        }
4756        final int callingPid = Binder.getCallingPid();
4757        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
4758                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
4759        long callingId = Binder.clearCallingIdentity();
4760        try {
4761            IPackageManager pm = AppGlobals.getPackageManager();
4762            synchronized(this) {
4763                int[] users = userId == UserHandle.USER_ALL
4764                        ? getUsersLocked() : new int[] { userId };
4765                for (int user : users) {
4766                    int pkgUid = -1;
4767                    try {
4768                        pkgUid = pm.getPackageUid(packageName, user);
4769                    } catch (RemoteException e) {
4770                    }
4771                    if (pkgUid == -1) {
4772                        Slog.w(TAG, "Invalid packageName: " + packageName);
4773                        continue;
4774                    }
4775                    try {
4776                        pm.setPackageStoppedState(packageName, true, user);
4777                    } catch (RemoteException e) {
4778                    } catch (IllegalArgumentException e) {
4779                        Slog.w(TAG, "Failed trying to unstop package "
4780                                + packageName + ": " + e);
4781                    }
4782                    if (isUserRunningLocked(user, false)) {
4783                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
4784                    }
4785                }
4786            }
4787        } finally {
4788            Binder.restoreCallingIdentity(callingId);
4789        }
4790    }
4791
4792    @Override
4793    public void addPackageDependency(String packageName) {
4794        synchronized (this) {
4795            int callingPid = Binder.getCallingPid();
4796            if (callingPid == Process.myPid()) {
4797                //  Yeah, um, no.
4798                Slog.w(TAG, "Can't addPackageDependency on system process");
4799                return;
4800            }
4801            ProcessRecord proc;
4802            synchronized (mPidsSelfLocked) {
4803                proc = mPidsSelfLocked.get(Binder.getCallingPid());
4804            }
4805            if (proc != null) {
4806                if (proc.pkgDeps == null) {
4807                    proc.pkgDeps = new ArraySet<String>(1);
4808                }
4809                proc.pkgDeps.add(packageName);
4810            }
4811        }
4812    }
4813
4814    /*
4815     * The pkg name and app id have to be specified.
4816     */
4817    @Override
4818    public void killApplicationWithAppId(String pkg, int appid, String reason) {
4819        if (pkg == null) {
4820            return;
4821        }
4822        // Make sure the uid is valid.
4823        if (appid < 0) {
4824            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
4825            return;
4826        }
4827        int callerUid = Binder.getCallingUid();
4828        // Only the system server can kill an application
4829        if (callerUid == Process.SYSTEM_UID) {
4830            // Post an aysnc message to kill the application
4831            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
4832            msg.arg1 = appid;
4833            msg.arg2 = 0;
4834            Bundle bundle = new Bundle();
4835            bundle.putString("pkg", pkg);
4836            bundle.putString("reason", reason);
4837            msg.obj = bundle;
4838            mHandler.sendMessage(msg);
4839        } else {
4840            throw new SecurityException(callerUid + " cannot kill pkg: " +
4841                    pkg);
4842        }
4843    }
4844
4845    @Override
4846    public void closeSystemDialogs(String reason) {
4847        enforceNotIsolatedCaller("closeSystemDialogs");
4848
4849        final int pid = Binder.getCallingPid();
4850        final int uid = Binder.getCallingUid();
4851        final long origId = Binder.clearCallingIdentity();
4852        try {
4853            synchronized (this) {
4854                // Only allow this from foreground processes, so that background
4855                // applications can't abuse it to prevent system UI from being shown.
4856                if (uid >= Process.FIRST_APPLICATION_UID) {
4857                    ProcessRecord proc;
4858                    synchronized (mPidsSelfLocked) {
4859                        proc = mPidsSelfLocked.get(pid);
4860                    }
4861                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
4862                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
4863                                + " from background process " + proc);
4864                        return;
4865                    }
4866                }
4867                closeSystemDialogsLocked(reason);
4868            }
4869        } finally {
4870            Binder.restoreCallingIdentity(origId);
4871        }
4872    }
4873
4874    void closeSystemDialogsLocked(String reason) {
4875        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
4876        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4877                | Intent.FLAG_RECEIVER_FOREGROUND);
4878        if (reason != null) {
4879            intent.putExtra("reason", reason);
4880        }
4881        mWindowManager.closeSystemDialogs(reason);
4882
4883        mStackSupervisor.closeSystemDialogsLocked();
4884
4885        broadcastIntentLocked(null, null, intent, null,
4886                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
4887                Process.SYSTEM_UID, UserHandle.USER_ALL);
4888    }
4889
4890    @Override
4891    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
4892        enforceNotIsolatedCaller("getProcessMemoryInfo");
4893        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
4894        for (int i=pids.length-1; i>=0; i--) {
4895            ProcessRecord proc;
4896            int oomAdj;
4897            synchronized (this) {
4898                synchronized (mPidsSelfLocked) {
4899                    proc = mPidsSelfLocked.get(pids[i]);
4900                    oomAdj = proc != null ? proc.setAdj : 0;
4901                }
4902            }
4903            infos[i] = new Debug.MemoryInfo();
4904            Debug.getMemoryInfo(pids[i], infos[i]);
4905            if (proc != null) {
4906                synchronized (this) {
4907                    if (proc.thread != null && proc.setAdj == oomAdj) {
4908                        // Record this for posterity if the process has been stable.
4909                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
4910                                infos[i].getTotalUss(), false, proc.pkgList);
4911                    }
4912                }
4913            }
4914        }
4915        return infos;
4916    }
4917
4918    @Override
4919    public long[] getProcessPss(int[] pids) {
4920        enforceNotIsolatedCaller("getProcessPss");
4921        long[] pss = new long[pids.length];
4922        for (int i=pids.length-1; i>=0; i--) {
4923            ProcessRecord proc;
4924            int oomAdj;
4925            synchronized (this) {
4926                synchronized (mPidsSelfLocked) {
4927                    proc = mPidsSelfLocked.get(pids[i]);
4928                    oomAdj = proc != null ? proc.setAdj : 0;
4929                }
4930            }
4931            long[] tmpUss = new long[1];
4932            pss[i] = Debug.getPss(pids[i], tmpUss);
4933            if (proc != null) {
4934                synchronized (this) {
4935                    if (proc.thread != null && proc.setAdj == oomAdj) {
4936                        // Record this for posterity if the process has been stable.
4937                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
4938                    }
4939                }
4940            }
4941        }
4942        return pss;
4943    }
4944
4945    @Override
4946    public void killApplicationProcess(String processName, int uid) {
4947        if (processName == null) {
4948            return;
4949        }
4950
4951        int callerUid = Binder.getCallingUid();
4952        // Only the system server can kill an application
4953        if (callerUid == Process.SYSTEM_UID) {
4954            synchronized (this) {
4955                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
4956                if (app != null && app.thread != null) {
4957                    try {
4958                        app.thread.scheduleSuicide();
4959                    } catch (RemoteException e) {
4960                        // If the other end already died, then our work here is done.
4961                    }
4962                } else {
4963                    Slog.w(TAG, "Process/uid not found attempting kill of "
4964                            + processName + " / " + uid);
4965                }
4966            }
4967        } else {
4968            throw new SecurityException(callerUid + " cannot kill app process: " +
4969                    processName);
4970        }
4971    }
4972
4973    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
4974        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
4975                false, true, false, false, UserHandle.getUserId(uid), reason);
4976        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
4977                Uri.fromParts("package", packageName, null));
4978        if (!mProcessesReady) {
4979            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4980                    | Intent.FLAG_RECEIVER_FOREGROUND);
4981        }
4982        intent.putExtra(Intent.EXTRA_UID, uid);
4983        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
4984        broadcastIntentLocked(null, null, intent,
4985                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4986                false, false,
4987                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
4988    }
4989
4990    private void forceStopUserLocked(int userId, String reason) {
4991        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
4992        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
4993        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
4994                | Intent.FLAG_RECEIVER_FOREGROUND);
4995        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4996        broadcastIntentLocked(null, null, intent,
4997                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
4998                false, false,
4999                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5000    }
5001
5002    private final boolean killPackageProcessesLocked(String packageName, int appId,
5003            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5004            boolean doit, boolean evenPersistent, String reason) {
5005        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5006
5007        // Remove all processes this package may have touched: all with the
5008        // same UID (except for the system or root user), and all whose name
5009        // matches the package name.
5010        final int NP = mProcessNames.getMap().size();
5011        for (int ip=0; ip<NP; ip++) {
5012            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5013            final int NA = apps.size();
5014            for (int ia=0; ia<NA; ia++) {
5015                ProcessRecord app = apps.valueAt(ia);
5016                if (app.persistent && !evenPersistent) {
5017                    // we don't kill persistent processes
5018                    continue;
5019                }
5020                if (app.removed) {
5021                    if (doit) {
5022                        procs.add(app);
5023                    }
5024                    continue;
5025                }
5026
5027                // Skip process if it doesn't meet our oom adj requirement.
5028                if (app.setAdj < minOomAdj) {
5029                    continue;
5030                }
5031
5032                // If no package is specified, we call all processes under the
5033                // give user id.
5034                if (packageName == null) {
5035                    if (app.userId != userId) {
5036                        continue;
5037                    }
5038                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5039                        continue;
5040                    }
5041                // Package has been specified, we want to hit all processes
5042                // that match it.  We need to qualify this by the processes
5043                // that are running under the specified app and user ID.
5044                } else {
5045                    final boolean isDep = app.pkgDeps != null
5046                            && app.pkgDeps.contains(packageName);
5047                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5048                        continue;
5049                    }
5050                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5051                        continue;
5052                    }
5053                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5054                        continue;
5055                    }
5056                }
5057
5058                // Process has passed all conditions, kill it!
5059                if (!doit) {
5060                    return true;
5061                }
5062                app.removed = true;
5063                procs.add(app);
5064            }
5065        }
5066
5067        int N = procs.size();
5068        for (int i=0; i<N; i++) {
5069            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5070        }
5071        updateOomAdjLocked();
5072        return N > 0;
5073    }
5074
5075    private final boolean forceStopPackageLocked(String name, int appId,
5076            boolean callerWillRestart, boolean purgeCache, boolean doit,
5077            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5078        int i;
5079        int N;
5080
5081        if (userId == UserHandle.USER_ALL && name == null) {
5082            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5083        }
5084
5085        if (appId < 0 && name != null) {
5086            try {
5087                appId = UserHandle.getAppId(
5088                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5089            } catch (RemoteException e) {
5090            }
5091        }
5092
5093        if (doit) {
5094            if (name != null) {
5095                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5096                        + " user=" + userId + ": " + reason);
5097            } else {
5098                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5099            }
5100
5101            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5102            for (int ip=pmap.size()-1; ip>=0; ip--) {
5103                SparseArray<Long> ba = pmap.valueAt(ip);
5104                for (i=ba.size()-1; i>=0; i--) {
5105                    boolean remove = false;
5106                    final int entUid = ba.keyAt(i);
5107                    if (name != null) {
5108                        if (userId == UserHandle.USER_ALL) {
5109                            if (UserHandle.getAppId(entUid) == appId) {
5110                                remove = true;
5111                            }
5112                        } else {
5113                            if (entUid == UserHandle.getUid(userId, appId)) {
5114                                remove = true;
5115                            }
5116                        }
5117                    } else if (UserHandle.getUserId(entUid) == userId) {
5118                        remove = true;
5119                    }
5120                    if (remove) {
5121                        ba.removeAt(i);
5122                    }
5123                }
5124                if (ba.size() == 0) {
5125                    pmap.removeAt(ip);
5126                }
5127            }
5128        }
5129
5130        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5131                -100, callerWillRestart, true, doit, evenPersistent,
5132                name == null ? ("stop user " + userId) : ("stop " + name));
5133
5134        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5135            if (!doit) {
5136                return true;
5137            }
5138            didSomething = true;
5139        }
5140
5141        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5142            if (!doit) {
5143                return true;
5144            }
5145            didSomething = true;
5146        }
5147
5148        if (name == null) {
5149            // Remove all sticky broadcasts from this user.
5150            mStickyBroadcasts.remove(userId);
5151        }
5152
5153        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5154        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5155                userId, providers)) {
5156            if (!doit) {
5157                return true;
5158            }
5159            didSomething = true;
5160        }
5161        N = providers.size();
5162        for (i=0; i<N; i++) {
5163            removeDyingProviderLocked(null, providers.get(i), true);
5164        }
5165
5166        // Remove transient permissions granted from/to this package/user
5167        removeUriPermissionsForPackageLocked(name, userId, false);
5168
5169        if (name == null || uninstalling) {
5170            // Remove pending intents.  For now we only do this when force
5171            // stopping users, because we have some problems when doing this
5172            // for packages -- app widgets are not currently cleaned up for
5173            // such packages, so they can be left with bad pending intents.
5174            if (mIntentSenderRecords.size() > 0) {
5175                Iterator<WeakReference<PendingIntentRecord>> it
5176                        = mIntentSenderRecords.values().iterator();
5177                while (it.hasNext()) {
5178                    WeakReference<PendingIntentRecord> wpir = it.next();
5179                    if (wpir == null) {
5180                        it.remove();
5181                        continue;
5182                    }
5183                    PendingIntentRecord pir = wpir.get();
5184                    if (pir == null) {
5185                        it.remove();
5186                        continue;
5187                    }
5188                    if (name == null) {
5189                        // Stopping user, remove all objects for the user.
5190                        if (pir.key.userId != userId) {
5191                            // Not the same user, skip it.
5192                            continue;
5193                        }
5194                    } else {
5195                        if (UserHandle.getAppId(pir.uid) != appId) {
5196                            // Different app id, skip it.
5197                            continue;
5198                        }
5199                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5200                            // Different user, skip it.
5201                            continue;
5202                        }
5203                        if (!pir.key.packageName.equals(name)) {
5204                            // Different package, skip it.
5205                            continue;
5206                        }
5207                    }
5208                    if (!doit) {
5209                        return true;
5210                    }
5211                    didSomething = true;
5212                    it.remove();
5213                    pir.canceled = true;
5214                    if (pir.key.activity != null) {
5215                        pir.key.activity.pendingResults.remove(pir.ref);
5216                    }
5217                }
5218            }
5219        }
5220
5221        if (doit) {
5222            if (purgeCache && name != null) {
5223                AttributeCache ac = AttributeCache.instance();
5224                if (ac != null) {
5225                    ac.removePackage(name);
5226                }
5227            }
5228            if (mBooted) {
5229                mStackSupervisor.resumeTopActivitiesLocked();
5230                mStackSupervisor.scheduleIdleLocked();
5231            }
5232        }
5233
5234        return didSomething;
5235    }
5236
5237    private final boolean removeProcessLocked(ProcessRecord app,
5238            boolean callerWillRestart, boolean allowRestart, String reason) {
5239        final String name = app.processName;
5240        final int uid = app.uid;
5241        if (DEBUG_PROCESSES) Slog.d(
5242            TAG, "Force removing proc " + app.toShortString() + " (" + name
5243            + "/" + uid + ")");
5244
5245        mProcessNames.remove(name, uid);
5246        mIsolatedProcesses.remove(app.uid);
5247        if (mHeavyWeightProcess == app) {
5248            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5249                    mHeavyWeightProcess.userId, 0));
5250            mHeavyWeightProcess = null;
5251        }
5252        boolean needRestart = false;
5253        if (app.pid > 0 && app.pid != MY_PID) {
5254            int pid = app.pid;
5255            synchronized (mPidsSelfLocked) {
5256                mPidsSelfLocked.remove(pid);
5257                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5258            }
5259            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5260            if (app.isolated) {
5261                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5262            }
5263            killUnneededProcessLocked(app, reason);
5264            Process.killProcessGroup(app.info.uid, app.pid);
5265            handleAppDiedLocked(app, true, allowRestart);
5266            removeLruProcessLocked(app);
5267
5268            if (app.persistent && !app.isolated) {
5269                if (!callerWillRestart) {
5270                    addAppLocked(app.info, false, null /* ABI override */);
5271                } else {
5272                    needRestart = true;
5273                }
5274            }
5275        } else {
5276            mRemovedProcesses.add(app);
5277        }
5278
5279        return needRestart;
5280    }
5281
5282    private final void processStartTimedOutLocked(ProcessRecord app) {
5283        final int pid = app.pid;
5284        boolean gone = false;
5285        synchronized (mPidsSelfLocked) {
5286            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5287            if (knownApp != null && knownApp.thread == null) {
5288                mPidsSelfLocked.remove(pid);
5289                gone = true;
5290            }
5291        }
5292
5293        if (gone) {
5294            Slog.w(TAG, "Process " + app + " failed to attach");
5295            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5296                    pid, app.uid, app.processName);
5297            mProcessNames.remove(app.processName, app.uid);
5298            mIsolatedProcesses.remove(app.uid);
5299            if (mHeavyWeightProcess == app) {
5300                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5301                        mHeavyWeightProcess.userId, 0));
5302                mHeavyWeightProcess = null;
5303            }
5304            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5305            if (app.isolated) {
5306                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5307            }
5308            // Take care of any launching providers waiting for this process.
5309            checkAppInLaunchingProvidersLocked(app, true);
5310            // Take care of any services that are waiting for the process.
5311            mServices.processStartTimedOutLocked(app);
5312            killUnneededProcessLocked(app, "start timeout");
5313            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5314                Slog.w(TAG, "Unattached app died before backup, skipping");
5315                try {
5316                    IBackupManager bm = IBackupManager.Stub.asInterface(
5317                            ServiceManager.getService(Context.BACKUP_SERVICE));
5318                    bm.agentDisconnected(app.info.packageName);
5319                } catch (RemoteException e) {
5320                    // Can't happen; the backup manager is local
5321                }
5322            }
5323            if (isPendingBroadcastProcessLocked(pid)) {
5324                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5325                skipPendingBroadcastLocked(pid);
5326            }
5327        } else {
5328            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5329        }
5330    }
5331
5332    private final boolean attachApplicationLocked(IApplicationThread thread,
5333            int pid) {
5334
5335        // Find the application record that is being attached...  either via
5336        // the pid if we are running in multiple processes, or just pull the
5337        // next app record if we are emulating process with anonymous threads.
5338        ProcessRecord app;
5339        if (pid != MY_PID && pid >= 0) {
5340            synchronized (mPidsSelfLocked) {
5341                app = mPidsSelfLocked.get(pid);
5342            }
5343        } else {
5344            app = null;
5345        }
5346
5347        if (app == null) {
5348            Slog.w(TAG, "No pending application record for pid " + pid
5349                    + " (IApplicationThread " + thread + "); dropping process");
5350            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5351            if (pid > 0 && pid != MY_PID) {
5352                Process.killProcessQuiet(pid);
5353                //TODO: Process.killProcessGroup(app.info.uid, pid);
5354            } else {
5355                try {
5356                    thread.scheduleExit();
5357                } catch (Exception e) {
5358                    // Ignore exceptions.
5359                }
5360            }
5361            return false;
5362        }
5363
5364        // If this application record is still attached to a previous
5365        // process, clean it up now.
5366        if (app.thread != null) {
5367            handleAppDiedLocked(app, true, true);
5368        }
5369
5370        // Tell the process all about itself.
5371
5372        if (localLOGV) Slog.v(
5373                TAG, "Binding process pid " + pid + " to record " + app);
5374
5375        final String processName = app.processName;
5376        try {
5377            AppDeathRecipient adr = new AppDeathRecipient(
5378                    app, pid, thread);
5379            thread.asBinder().linkToDeath(adr, 0);
5380            app.deathRecipient = adr;
5381        } catch (RemoteException e) {
5382            app.resetPackageList(mProcessStats);
5383            startProcessLocked(app, "link fail", processName, null /* ABI override */,
5384                    null /* entryPoint */, null /* entryPointArgs */);
5385            return false;
5386        }
5387
5388        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5389
5390        app.makeActive(thread, mProcessStats);
5391        app.curAdj = app.setAdj = -100;
5392        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5393        app.forcingToForeground = null;
5394        updateProcessForegroundLocked(app, false, false);
5395        app.hasShownUi = false;
5396        app.debugging = false;
5397        app.cached = false;
5398
5399        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5400
5401        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5402        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5403
5404        if (!normalMode) {
5405            Slog.i(TAG, "Launching preboot mode app: " + app);
5406        }
5407
5408        if (localLOGV) Slog.v(
5409            TAG, "New app record " + app
5410            + " thread=" + thread.asBinder() + " pid=" + pid);
5411        try {
5412            int testMode = IApplicationThread.DEBUG_OFF;
5413            if (mDebugApp != null && mDebugApp.equals(processName)) {
5414                testMode = mWaitForDebugger
5415                    ? IApplicationThread.DEBUG_WAIT
5416                    : IApplicationThread.DEBUG_ON;
5417                app.debugging = true;
5418                if (mDebugTransient) {
5419                    mDebugApp = mOrigDebugApp;
5420                    mWaitForDebugger = mOrigWaitForDebugger;
5421                }
5422            }
5423            String profileFile = app.instrumentationProfileFile;
5424            ParcelFileDescriptor profileFd = null;
5425            boolean profileAutoStop = false;
5426            if (mProfileApp != null && mProfileApp.equals(processName)) {
5427                mProfileProc = app;
5428                profileFile = mProfileFile;
5429                profileFd = mProfileFd;
5430                profileAutoStop = mAutoStopProfiler;
5431            }
5432            boolean enableOpenGlTrace = false;
5433            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5434                enableOpenGlTrace = true;
5435                mOpenGlTraceApp = null;
5436            }
5437
5438            // If the app is being launched for restore or full backup, set it up specially
5439            boolean isRestrictedBackupMode = false;
5440            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5441                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5442                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5443                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5444            }
5445
5446            ensurePackageDexOpt(app.instrumentationInfo != null
5447                    ? app.instrumentationInfo.packageName
5448                    : app.info.packageName);
5449            if (app.instrumentationClass != null) {
5450                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5451            }
5452            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
5453                    + processName + " with config " + mConfiguration);
5454            ApplicationInfo appInfo = app.instrumentationInfo != null
5455                    ? app.instrumentationInfo : app.info;
5456            app.compat = compatibilityInfoForPackageLocked(appInfo);
5457            if (profileFd != null) {
5458                profileFd = profileFd.dup();
5459            }
5460            thread.bindApplication(processName, appInfo, providers,
5461                    app.instrumentationClass, profileFile, profileFd, profileAutoStop,
5462                    app.instrumentationArguments, app.instrumentationWatcher,
5463                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
5464                    isRestrictedBackupMode || !normalMode, app.persistent,
5465                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
5466                    mCoreSettingsObserver.getCoreSettingsLocked());
5467            updateLruProcessLocked(app, false, null);
5468            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
5469        } catch (Exception e) {
5470            // todo: Yikes!  What should we do?  For now we will try to
5471            // start another process, but that could easily get us in
5472            // an infinite loop of restarting processes...
5473            Slog.w(TAG, "Exception thrown during bind!", e);
5474
5475            app.resetPackageList(mProcessStats);
5476            app.unlinkDeathRecipient();
5477            startProcessLocked(app, "bind fail", processName, null /* ABI override */,
5478                    null /* entryPoint */, null /* entryPointArgs */);
5479            return false;
5480        }
5481
5482        // Remove this record from the list of starting applications.
5483        mPersistentStartingProcesses.remove(app);
5484        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
5485                "Attach application locked removing on hold: " + app);
5486        mProcessesOnHold.remove(app);
5487
5488        boolean badApp = false;
5489        boolean didSomething = false;
5490
5491        // See if the top visible activity is waiting to run in this process...
5492        if (normalMode) {
5493            try {
5494                if (mStackSupervisor.attachApplicationLocked(app)) {
5495                    didSomething = true;
5496                }
5497            } catch (Exception e) {
5498                badApp = true;
5499            }
5500        }
5501
5502        // Find any services that should be running in this process...
5503        if (!badApp) {
5504            try {
5505                didSomething |= mServices.attachApplicationLocked(app, processName);
5506            } catch (Exception e) {
5507                badApp = true;
5508            }
5509        }
5510
5511        // Check if a next-broadcast receiver is in this process...
5512        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
5513            try {
5514                didSomething |= sendPendingBroadcastsLocked(app);
5515            } catch (Exception e) {
5516                // If the app died trying to launch the receiver we declare it 'bad'
5517                badApp = true;
5518            }
5519        }
5520
5521        // Check whether the next backup agent is in this process...
5522        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
5523            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
5524            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
5525            try {
5526                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
5527                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
5528                        mBackupTarget.backupMode);
5529            } catch (Exception e) {
5530                Slog.w(TAG, "Exception scheduling backup agent creation: ");
5531                e.printStackTrace();
5532            }
5533        }
5534
5535        if (badApp) {
5536            // todo: Also need to kill application to deal with all
5537            // kinds of exceptions.
5538            handleAppDiedLocked(app, false, true);
5539            return false;
5540        }
5541
5542        if (!didSomething) {
5543            updateOomAdjLocked();
5544        }
5545
5546        return true;
5547    }
5548
5549    @Override
5550    public final void attachApplication(IApplicationThread thread) {
5551        synchronized (this) {
5552            int callingPid = Binder.getCallingPid();
5553            final long origId = Binder.clearCallingIdentity();
5554            attachApplicationLocked(thread, callingPid);
5555            Binder.restoreCallingIdentity(origId);
5556        }
5557    }
5558
5559    @Override
5560    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
5561        final long origId = Binder.clearCallingIdentity();
5562        synchronized (this) {
5563            ActivityStack stack = ActivityRecord.getStackLocked(token);
5564            if (stack != null) {
5565                ActivityRecord r =
5566                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
5567                if (stopProfiling) {
5568                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
5569                        try {
5570                            mProfileFd.close();
5571                        } catch (IOException e) {
5572                        }
5573                        clearProfilerLocked();
5574                    }
5575                }
5576            }
5577        }
5578        Binder.restoreCallingIdentity(origId);
5579    }
5580
5581    void postEnableScreenAfterBootLocked() {
5582        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
5583    }
5584
5585    void enableScreenAfterBoot() {
5586        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
5587                SystemClock.uptimeMillis());
5588        mWindowManager.enableScreenAfterBoot();
5589
5590        synchronized (this) {
5591            updateEventDispatchingLocked();
5592        }
5593    }
5594
5595    @Override
5596    public void showBootMessage(final CharSequence msg, final boolean always) {
5597        enforceNotIsolatedCaller("showBootMessage");
5598        mWindowManager.showBootMessage(msg, always);
5599    }
5600
5601    @Override
5602    public void dismissKeyguardOnNextActivity() {
5603        enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
5604        final long token = Binder.clearCallingIdentity();
5605        try {
5606            synchronized (this) {
5607                if (DEBUG_LOCKSCREEN) logLockScreen("");
5608                if (mLockScreenShown) {
5609                    mLockScreenShown = false;
5610                    comeOutOfSleepIfNeededLocked();
5611                }
5612                mStackSupervisor.setDismissKeyguard(true);
5613            }
5614        } finally {
5615            Binder.restoreCallingIdentity(token);
5616        }
5617    }
5618
5619    final void finishBooting() {
5620        // Register receivers to handle package update events
5621        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
5622
5623        synchronized (this) {
5624            // Ensure that any processes we had put on hold are now started
5625            // up.
5626            final int NP = mProcessesOnHold.size();
5627            if (NP > 0) {
5628                ArrayList<ProcessRecord> procs =
5629                    new ArrayList<ProcessRecord>(mProcessesOnHold);
5630                for (int ip=0; ip<NP; ip++) {
5631                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
5632                            + procs.get(ip));
5633                    startProcessLocked(procs.get(ip), "on-hold", null, null /* ABI override */,
5634                            null /* entryPoint */, null /* entryPointArgs */);
5635                }
5636            }
5637
5638            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
5639                // Start looking for apps that are abusing wake locks.
5640                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5641                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
5642                // Tell anyone interested that we are done booting!
5643                SystemProperties.set("sys.boot_completed", "1");
5644                SystemProperties.set("dev.bootcomplete", "1");
5645                for (int i=0; i<mStartedUsers.size(); i++) {
5646                    UserStartedState uss = mStartedUsers.valueAt(i);
5647                    if (uss.mState == UserStartedState.STATE_BOOTING) {
5648                        uss.mState = UserStartedState.STATE_RUNNING;
5649                        final int userId = mStartedUsers.keyAt(i);
5650                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
5651                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5652                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
5653                        broadcastIntentLocked(null, null, intent, null,
5654                                new IIntentReceiver.Stub() {
5655                                    @Override
5656                                    public void performReceive(Intent intent, int resultCode,
5657                                            String data, Bundle extras, boolean ordered,
5658                                            boolean sticky, int sendingUser) {
5659                                        synchronized (ActivityManagerService.this) {
5660                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
5661                                                    true, false);
5662                                        }
5663                                    }
5664                                },
5665                                0, null, null,
5666                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
5667                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
5668                                userId);
5669                    }
5670                }
5671                scheduleStartProfilesLocked();
5672            }
5673        }
5674    }
5675
5676    final void ensureBootCompleted() {
5677        boolean booting;
5678        boolean enableScreen;
5679        synchronized (this) {
5680            booting = mBooting;
5681            mBooting = false;
5682            enableScreen = !mBooted;
5683            mBooted = true;
5684        }
5685
5686        if (booting) {
5687            finishBooting();
5688        }
5689
5690        if (enableScreen) {
5691            enableScreenAfterBoot();
5692        }
5693    }
5694
5695    @Override
5696    public final void activityResumed(IBinder token) {
5697        final long origId = Binder.clearCallingIdentity();
5698        synchronized(this) {
5699            ActivityStack stack = ActivityRecord.getStackLocked(token);
5700            if (stack != null) {
5701                ActivityRecord.activityResumedLocked(token);
5702            }
5703        }
5704        Binder.restoreCallingIdentity(origId);
5705    }
5706
5707    @Override
5708    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
5709        final long origId = Binder.clearCallingIdentity();
5710        synchronized(this) {
5711            ActivityStack stack = ActivityRecord.getStackLocked(token);
5712            if (stack != null) {
5713                stack.activityPausedLocked(token, false, persistentState);
5714            }
5715        }
5716        Binder.restoreCallingIdentity(origId);
5717    }
5718
5719    @Override
5720    public final void activityStopped(IBinder token, Bundle icicle,
5721            PersistableBundle persistentState, CharSequence description) {
5722        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
5723
5724        // Refuse possible leaked file descriptors
5725        if (icicle != null && icicle.hasFileDescriptors()) {
5726            throw new IllegalArgumentException("File descriptors passed in Bundle");
5727        }
5728
5729        final long origId = Binder.clearCallingIdentity();
5730
5731        synchronized (this) {
5732            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5733            if (r != null) {
5734                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
5735            }
5736        }
5737
5738        trimApplications();
5739
5740        Binder.restoreCallingIdentity(origId);
5741    }
5742
5743    @Override
5744    public final void activityDestroyed(IBinder token) {
5745        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
5746        synchronized (this) {
5747            ActivityStack stack = ActivityRecord.getStackLocked(token);
5748            if (stack != null) {
5749                stack.activityDestroyedLocked(token);
5750            }
5751        }
5752    }
5753
5754    @Override
5755    public final void mediaResourcesReleased(IBinder token) {
5756        final long origId = Binder.clearCallingIdentity();
5757        try {
5758            synchronized (this) {
5759                ActivityStack stack = ActivityRecord.getStackLocked(token);
5760                if (stack != null) {
5761                    stack.mediaResourcesReleased(token);
5762                }
5763            }
5764        } finally {
5765            Binder.restoreCallingIdentity(origId);
5766        }
5767    }
5768
5769    @Override
5770    public final void notifyLaunchTaskBehindComplete(IBinder token) {
5771        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
5772    }
5773
5774    @Override
5775    public final void notifyEnterAnimationComplete(IBinder token) {
5776        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
5777    }
5778
5779    @Override
5780    public String getCallingPackage(IBinder token) {
5781        synchronized (this) {
5782            ActivityRecord r = getCallingRecordLocked(token);
5783            return r != null ? r.info.packageName : null;
5784        }
5785    }
5786
5787    @Override
5788    public ComponentName getCallingActivity(IBinder token) {
5789        synchronized (this) {
5790            ActivityRecord r = getCallingRecordLocked(token);
5791            return r != null ? r.intent.getComponent() : null;
5792        }
5793    }
5794
5795    private ActivityRecord getCallingRecordLocked(IBinder token) {
5796        ActivityRecord r = ActivityRecord.isInStackLocked(token);
5797        if (r == null) {
5798            return null;
5799        }
5800        return r.resultTo;
5801    }
5802
5803    @Override
5804    public ComponentName getActivityClassForToken(IBinder token) {
5805        synchronized(this) {
5806            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5807            if (r == null) {
5808                return null;
5809            }
5810            return r.intent.getComponent();
5811        }
5812    }
5813
5814    @Override
5815    public String getPackageForToken(IBinder token) {
5816        synchronized(this) {
5817            ActivityRecord r = ActivityRecord.isInStackLocked(token);
5818            if (r == null) {
5819                return null;
5820            }
5821            return r.packageName;
5822        }
5823    }
5824
5825    @Override
5826    public IIntentSender getIntentSender(int type,
5827            String packageName, IBinder token, String resultWho,
5828            int requestCode, Intent[] intents, String[] resolvedTypes,
5829            int flags, Bundle options, int userId) {
5830        enforceNotIsolatedCaller("getIntentSender");
5831        // Refuse possible leaked file descriptors
5832        if (intents != null) {
5833            if (intents.length < 1) {
5834                throw new IllegalArgumentException("Intents array length must be >= 1");
5835            }
5836            for (int i=0; i<intents.length; i++) {
5837                Intent intent = intents[i];
5838                if (intent != null) {
5839                    if (intent.hasFileDescriptors()) {
5840                        throw new IllegalArgumentException("File descriptors passed in Intent");
5841                    }
5842                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
5843                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
5844                        throw new IllegalArgumentException(
5845                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
5846                    }
5847                    intents[i] = new Intent(intent);
5848                }
5849            }
5850            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
5851                throw new IllegalArgumentException(
5852                        "Intent array length does not match resolvedTypes length");
5853            }
5854        }
5855        if (options != null) {
5856            if (options.hasFileDescriptors()) {
5857                throw new IllegalArgumentException("File descriptors passed in options");
5858            }
5859        }
5860
5861        synchronized(this) {
5862            int callingUid = Binder.getCallingUid();
5863            int origUserId = userId;
5864            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
5865                    type == ActivityManager.INTENT_SENDER_BROADCAST,
5866                    ALLOW_NON_FULL, "getIntentSender", null);
5867            if (origUserId == UserHandle.USER_CURRENT) {
5868                // We don't want to evaluate this until the pending intent is
5869                // actually executed.  However, we do want to always do the
5870                // security checking for it above.
5871                userId = UserHandle.USER_CURRENT;
5872            }
5873            try {
5874                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
5875                    int uid = AppGlobals.getPackageManager()
5876                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
5877                    if (!UserHandle.isSameApp(callingUid, uid)) {
5878                        String msg = "Permission Denial: getIntentSender() from pid="
5879                            + Binder.getCallingPid()
5880                            + ", uid=" + Binder.getCallingUid()
5881                            + ", (need uid=" + uid + ")"
5882                            + " is not allowed to send as package " + packageName;
5883                        Slog.w(TAG, msg);
5884                        throw new SecurityException(msg);
5885                    }
5886                }
5887
5888                return getIntentSenderLocked(type, packageName, callingUid, userId,
5889                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
5890
5891            } catch (RemoteException e) {
5892                throw new SecurityException(e);
5893            }
5894        }
5895    }
5896
5897    IIntentSender getIntentSenderLocked(int type, String packageName,
5898            int callingUid, int userId, IBinder token, String resultWho,
5899            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
5900            Bundle options) {
5901        if (DEBUG_MU)
5902            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
5903        ActivityRecord activity = null;
5904        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5905            activity = ActivityRecord.isInStackLocked(token);
5906            if (activity == null) {
5907                return null;
5908            }
5909            if (activity.finishing) {
5910                return null;
5911            }
5912        }
5913
5914        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
5915        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
5916        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
5917        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
5918                |PendingIntent.FLAG_UPDATE_CURRENT);
5919
5920        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
5921                type, packageName, activity, resultWho,
5922                requestCode, intents, resolvedTypes, flags, options, userId);
5923        WeakReference<PendingIntentRecord> ref;
5924        ref = mIntentSenderRecords.get(key);
5925        PendingIntentRecord rec = ref != null ? ref.get() : null;
5926        if (rec != null) {
5927            if (!cancelCurrent) {
5928                if (updateCurrent) {
5929                    if (rec.key.requestIntent != null) {
5930                        rec.key.requestIntent.replaceExtras(intents != null ?
5931                                intents[intents.length - 1] : null);
5932                    }
5933                    if (intents != null) {
5934                        intents[intents.length-1] = rec.key.requestIntent;
5935                        rec.key.allIntents = intents;
5936                        rec.key.allResolvedTypes = resolvedTypes;
5937                    } else {
5938                        rec.key.allIntents = null;
5939                        rec.key.allResolvedTypes = null;
5940                    }
5941                }
5942                return rec;
5943            }
5944            rec.canceled = true;
5945            mIntentSenderRecords.remove(key);
5946        }
5947        if (noCreate) {
5948            return rec;
5949        }
5950        rec = new PendingIntentRecord(this, key, callingUid);
5951        mIntentSenderRecords.put(key, rec.ref);
5952        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
5953            if (activity.pendingResults == null) {
5954                activity.pendingResults
5955                        = new HashSet<WeakReference<PendingIntentRecord>>();
5956            }
5957            activity.pendingResults.add(rec.ref);
5958        }
5959        return rec;
5960    }
5961
5962    @Override
5963    public void cancelIntentSender(IIntentSender sender) {
5964        if (!(sender instanceof PendingIntentRecord)) {
5965            return;
5966        }
5967        synchronized(this) {
5968            PendingIntentRecord rec = (PendingIntentRecord)sender;
5969            try {
5970                int uid = AppGlobals.getPackageManager()
5971                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
5972                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
5973                    String msg = "Permission Denial: cancelIntentSender() from pid="
5974                        + Binder.getCallingPid()
5975                        + ", uid=" + Binder.getCallingUid()
5976                        + " is not allowed to cancel packges "
5977                        + rec.key.packageName;
5978                    Slog.w(TAG, msg);
5979                    throw new SecurityException(msg);
5980                }
5981            } catch (RemoteException e) {
5982                throw new SecurityException(e);
5983            }
5984            cancelIntentSenderLocked(rec, true);
5985        }
5986    }
5987
5988    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
5989        rec.canceled = true;
5990        mIntentSenderRecords.remove(rec.key);
5991        if (cleanActivity && rec.key.activity != null) {
5992            rec.key.activity.pendingResults.remove(rec.ref);
5993        }
5994    }
5995
5996    @Override
5997    public String getPackageForIntentSender(IIntentSender pendingResult) {
5998        if (!(pendingResult instanceof PendingIntentRecord)) {
5999            return null;
6000        }
6001        try {
6002            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6003            return res.key.packageName;
6004        } catch (ClassCastException e) {
6005        }
6006        return null;
6007    }
6008
6009    @Override
6010    public int getUidForIntentSender(IIntentSender sender) {
6011        if (sender instanceof PendingIntentRecord) {
6012            try {
6013                PendingIntentRecord res = (PendingIntentRecord)sender;
6014                return res.uid;
6015            } catch (ClassCastException e) {
6016            }
6017        }
6018        return -1;
6019    }
6020
6021    @Override
6022    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6023        if (!(pendingResult instanceof PendingIntentRecord)) {
6024            return false;
6025        }
6026        try {
6027            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6028            if (res.key.allIntents == null) {
6029                return false;
6030            }
6031            for (int i=0; i<res.key.allIntents.length; i++) {
6032                Intent intent = res.key.allIntents[i];
6033                if (intent.getPackage() != null && intent.getComponent() != null) {
6034                    return false;
6035                }
6036            }
6037            return true;
6038        } catch (ClassCastException e) {
6039        }
6040        return false;
6041    }
6042
6043    @Override
6044    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6045        if (!(pendingResult instanceof PendingIntentRecord)) {
6046            return false;
6047        }
6048        try {
6049            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6050            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6051                return true;
6052            }
6053            return false;
6054        } catch (ClassCastException e) {
6055        }
6056        return false;
6057    }
6058
6059    @Override
6060    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6061        if (!(pendingResult instanceof PendingIntentRecord)) {
6062            return null;
6063        }
6064        try {
6065            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6066            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6067        } catch (ClassCastException e) {
6068        }
6069        return null;
6070    }
6071
6072    @Override
6073    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6074        if (!(pendingResult instanceof PendingIntentRecord)) {
6075            return null;
6076        }
6077        try {
6078            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6079            Intent intent = res.key.requestIntent;
6080            if (intent != null) {
6081                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6082                        || res.lastTagPrefix.equals(prefix))) {
6083                    return res.lastTag;
6084                }
6085                res.lastTagPrefix = prefix;
6086                StringBuilder sb = new StringBuilder(128);
6087                if (prefix != null) {
6088                    sb.append(prefix);
6089                }
6090                if (intent.getAction() != null) {
6091                    sb.append(intent.getAction());
6092                } else if (intent.getComponent() != null) {
6093                    intent.getComponent().appendShortString(sb);
6094                } else {
6095                    sb.append("?");
6096                }
6097                return res.lastTag = sb.toString();
6098            }
6099        } catch (ClassCastException e) {
6100        }
6101        return null;
6102    }
6103
6104    @Override
6105    public void setProcessLimit(int max) {
6106        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6107                "setProcessLimit()");
6108        synchronized (this) {
6109            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6110            mProcessLimitOverride = max;
6111        }
6112        trimApplications();
6113    }
6114
6115    @Override
6116    public int getProcessLimit() {
6117        synchronized (this) {
6118            return mProcessLimitOverride;
6119        }
6120    }
6121
6122    void foregroundTokenDied(ForegroundToken token) {
6123        synchronized (ActivityManagerService.this) {
6124            synchronized (mPidsSelfLocked) {
6125                ForegroundToken cur
6126                    = mForegroundProcesses.get(token.pid);
6127                if (cur != token) {
6128                    return;
6129                }
6130                mForegroundProcesses.remove(token.pid);
6131                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6132                if (pr == null) {
6133                    return;
6134                }
6135                pr.forcingToForeground = null;
6136                updateProcessForegroundLocked(pr, false, false);
6137            }
6138            updateOomAdjLocked();
6139        }
6140    }
6141
6142    @Override
6143    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6144        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6145                "setProcessForeground()");
6146        synchronized(this) {
6147            boolean changed = false;
6148
6149            synchronized (mPidsSelfLocked) {
6150                ProcessRecord pr = mPidsSelfLocked.get(pid);
6151                if (pr == null && isForeground) {
6152                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6153                    return;
6154                }
6155                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6156                if (oldToken != null) {
6157                    oldToken.token.unlinkToDeath(oldToken, 0);
6158                    mForegroundProcesses.remove(pid);
6159                    if (pr != null) {
6160                        pr.forcingToForeground = null;
6161                    }
6162                    changed = true;
6163                }
6164                if (isForeground && token != null) {
6165                    ForegroundToken newToken = new ForegroundToken() {
6166                        @Override
6167                        public void binderDied() {
6168                            foregroundTokenDied(this);
6169                        }
6170                    };
6171                    newToken.pid = pid;
6172                    newToken.token = token;
6173                    try {
6174                        token.linkToDeath(newToken, 0);
6175                        mForegroundProcesses.put(pid, newToken);
6176                        pr.forcingToForeground = token;
6177                        changed = true;
6178                    } catch (RemoteException e) {
6179                        // If the process died while doing this, we will later
6180                        // do the cleanup with the process death link.
6181                    }
6182                }
6183            }
6184
6185            if (changed) {
6186                updateOomAdjLocked();
6187            }
6188        }
6189    }
6190
6191    // =========================================================
6192    // PERMISSIONS
6193    // =========================================================
6194
6195    static class PermissionController extends IPermissionController.Stub {
6196        ActivityManagerService mActivityManagerService;
6197        PermissionController(ActivityManagerService activityManagerService) {
6198            mActivityManagerService = activityManagerService;
6199        }
6200
6201        @Override
6202        public boolean checkPermission(String permission, int pid, int uid) {
6203            return mActivityManagerService.checkPermission(permission, pid,
6204                    uid) == PackageManager.PERMISSION_GRANTED;
6205        }
6206    }
6207
6208    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6209        @Override
6210        public int checkComponentPermission(String permission, int pid, int uid,
6211                int owningUid, boolean exported) {
6212            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6213                    owningUid, exported);
6214        }
6215
6216        @Override
6217        public Object getAMSLock() {
6218            return ActivityManagerService.this;
6219        }
6220    }
6221
6222    /**
6223     * This can be called with or without the global lock held.
6224     */
6225    int checkComponentPermission(String permission, int pid, int uid,
6226            int owningUid, boolean exported) {
6227        // We might be performing an operation on behalf of an indirect binder
6228        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6229        // client identity accordingly before proceeding.
6230        Identity tlsIdentity = sCallerIdentity.get();
6231        if (tlsIdentity != null) {
6232            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6233                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6234            uid = tlsIdentity.uid;
6235            pid = tlsIdentity.pid;
6236        }
6237
6238        if (pid == MY_PID) {
6239            return PackageManager.PERMISSION_GRANTED;
6240        }
6241
6242        return ActivityManager.checkComponentPermission(permission, uid,
6243                owningUid, exported);
6244    }
6245
6246    /**
6247     * As the only public entry point for permissions checking, this method
6248     * can enforce the semantic that requesting a check on a null global
6249     * permission is automatically denied.  (Internally a null permission
6250     * string is used when calling {@link #checkComponentPermission} in cases
6251     * when only uid-based security is needed.)
6252     *
6253     * This can be called with or without the global lock held.
6254     */
6255    @Override
6256    public int checkPermission(String permission, int pid, int uid) {
6257        if (permission == null) {
6258            return PackageManager.PERMISSION_DENIED;
6259        }
6260        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6261    }
6262
6263    /**
6264     * Binder IPC calls go through the public entry point.
6265     * This can be called with or without the global lock held.
6266     */
6267    int checkCallingPermission(String permission) {
6268        return checkPermission(permission,
6269                Binder.getCallingPid(),
6270                UserHandle.getAppId(Binder.getCallingUid()));
6271    }
6272
6273    /**
6274     * This can be called with or without the global lock held.
6275     */
6276    void enforceCallingPermission(String permission, String func) {
6277        if (checkCallingPermission(permission)
6278                == PackageManager.PERMISSION_GRANTED) {
6279            return;
6280        }
6281
6282        String msg = "Permission Denial: " + func + " from pid="
6283                + Binder.getCallingPid()
6284                + ", uid=" + Binder.getCallingUid()
6285                + " requires " + permission;
6286        Slog.w(TAG, msg);
6287        throw new SecurityException(msg);
6288    }
6289
6290    /**
6291     * Determine if UID is holding permissions required to access {@link Uri} in
6292     * the given {@link ProviderInfo}. Final permission checking is always done
6293     * in {@link ContentProvider}.
6294     */
6295    private final boolean checkHoldingPermissionsLocked(
6296            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6297        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6298                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6299        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6300            return false;
6301        }
6302        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6303    }
6304
6305    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6306            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6307        if (pi.applicationInfo.uid == uid) {
6308            return true;
6309        } else if (!pi.exported) {
6310            return false;
6311        }
6312
6313        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6314        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6315        try {
6316            // check if target holds top-level <provider> permissions
6317            if (!readMet && pi.readPermission != null && considerUidPermissions
6318                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6319                readMet = true;
6320            }
6321            if (!writeMet && pi.writePermission != null && considerUidPermissions
6322                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6323                writeMet = true;
6324            }
6325
6326            // track if unprotected read/write is allowed; any denied
6327            // <path-permission> below removes this ability
6328            boolean allowDefaultRead = pi.readPermission == null;
6329            boolean allowDefaultWrite = pi.writePermission == null;
6330
6331            // check if target holds any <path-permission> that match uri
6332            final PathPermission[] pps = pi.pathPermissions;
6333            if (pps != null) {
6334                final String path = grantUri.uri.getPath();
6335                int i = pps.length;
6336                while (i > 0 && (!readMet || !writeMet)) {
6337                    i--;
6338                    PathPermission pp = pps[i];
6339                    if (pp.match(path)) {
6340                        if (!readMet) {
6341                            final String pprperm = pp.getReadPermission();
6342                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6343                                    + pprperm + " for " + pp.getPath()
6344                                    + ": match=" + pp.match(path)
6345                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6346                            if (pprperm != null) {
6347                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6348                                        == PERMISSION_GRANTED) {
6349                                    readMet = true;
6350                                } else {
6351                                    allowDefaultRead = false;
6352                                }
6353                            }
6354                        }
6355                        if (!writeMet) {
6356                            final String ppwperm = pp.getWritePermission();
6357                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6358                                    + ppwperm + " for " + pp.getPath()
6359                                    + ": match=" + pp.match(path)
6360                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6361                            if (ppwperm != null) {
6362                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6363                                        == PERMISSION_GRANTED) {
6364                                    writeMet = true;
6365                                } else {
6366                                    allowDefaultWrite = false;
6367                                }
6368                            }
6369                        }
6370                    }
6371                }
6372            }
6373
6374            // grant unprotected <provider> read/write, if not blocked by
6375            // <path-permission> above
6376            if (allowDefaultRead) readMet = true;
6377            if (allowDefaultWrite) writeMet = true;
6378
6379        } catch (RemoteException e) {
6380            return false;
6381        }
6382
6383        return readMet && writeMet;
6384    }
6385
6386    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6387        ProviderInfo pi = null;
6388        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6389        if (cpr != null) {
6390            pi = cpr.info;
6391        } else {
6392            try {
6393                pi = AppGlobals.getPackageManager().resolveContentProvider(
6394                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6395            } catch (RemoteException ex) {
6396            }
6397        }
6398        return pi;
6399    }
6400
6401    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6402        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6403        if (targetUris != null) {
6404            return targetUris.get(grantUri);
6405        }
6406        return null;
6407    }
6408
6409    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6410            String targetPkg, int targetUid, GrantUri grantUri) {
6411        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6412        if (targetUris == null) {
6413            targetUris = Maps.newArrayMap();
6414            mGrantedUriPermissions.put(targetUid, targetUris);
6415        }
6416
6417        UriPermission perm = targetUris.get(grantUri);
6418        if (perm == null) {
6419            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6420            targetUris.put(grantUri, perm);
6421        }
6422
6423        return perm;
6424    }
6425
6426    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6427            final int modeFlags) {
6428        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6429        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6430                : UriPermission.STRENGTH_OWNED;
6431
6432        // Root gets to do everything.
6433        if (uid == 0) {
6434            return true;
6435        }
6436
6437        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6438        if (perms == null) return false;
6439
6440        // First look for exact match
6441        final UriPermission exactPerm = perms.get(grantUri);
6442        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6443            return true;
6444        }
6445
6446        // No exact match, look for prefixes
6447        final int N = perms.size();
6448        for (int i = 0; i < N; i++) {
6449            final UriPermission perm = perms.valueAt(i);
6450            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6451                    && perm.getStrength(modeFlags) >= minStrength) {
6452                return true;
6453            }
6454        }
6455
6456        return false;
6457    }
6458
6459    @Override
6460    public int checkUriPermission(Uri uri, int pid, int uid,
6461            final int modeFlags, int userId) {
6462        enforceNotIsolatedCaller("checkUriPermission");
6463
6464        // Another redirected-binder-call permissions check as in
6465        // {@link checkComponentPermission}.
6466        Identity tlsIdentity = sCallerIdentity.get();
6467        if (tlsIdentity != null) {
6468            uid = tlsIdentity.uid;
6469            pid = tlsIdentity.pid;
6470        }
6471
6472        // Our own process gets to do everything.
6473        if (pid == MY_PID) {
6474            return PackageManager.PERMISSION_GRANTED;
6475        }
6476        synchronized (this) {
6477            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
6478                    ? PackageManager.PERMISSION_GRANTED
6479                    : PackageManager.PERMISSION_DENIED;
6480        }
6481    }
6482
6483    /**
6484     * Check if the targetPkg can be granted permission to access uri by
6485     * the callingUid using the given modeFlags.  Throws a security exception
6486     * if callingUid is not allowed to do this.  Returns the uid of the target
6487     * if the URI permission grant should be performed; returns -1 if it is not
6488     * needed (for example targetPkg already has permission to access the URI).
6489     * If you already know the uid of the target, you can supply it in
6490     * lastTargetUid else set that to -1.
6491     */
6492    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6493            final int modeFlags, int lastTargetUid) {
6494        if (!Intent.isAccessUriMode(modeFlags)) {
6495            return -1;
6496        }
6497
6498        if (targetPkg != null) {
6499            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6500                    "Checking grant " + targetPkg + " permission to " + grantUri);
6501        }
6502
6503        final IPackageManager pm = AppGlobals.getPackageManager();
6504
6505        // If this is not a content: uri, we can't do anything with it.
6506        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
6507            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6508                    "Can't grant URI permission for non-content URI: " + grantUri);
6509            return -1;
6510        }
6511
6512        final String authority = grantUri.uri.getAuthority();
6513        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6514        if (pi == null) {
6515            Slog.w(TAG, "No content provider found for permission check: " +
6516                    grantUri.uri.toSafeString());
6517            return -1;
6518        }
6519
6520        int targetUid = lastTargetUid;
6521        if (targetUid < 0 && targetPkg != null) {
6522            try {
6523                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
6524                if (targetUid < 0) {
6525                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6526                            "Can't grant URI permission no uid for: " + targetPkg);
6527                    return -1;
6528                }
6529            } catch (RemoteException ex) {
6530                return -1;
6531            }
6532        }
6533
6534        if (targetUid >= 0) {
6535            // First...  does the target actually need this permission?
6536            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
6537                // No need to grant the target this permission.
6538                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6539                        "Target " + targetPkg + " already has full permission to " + grantUri);
6540                return -1;
6541            }
6542        } else {
6543            // First...  there is no target package, so can anyone access it?
6544            boolean allowed = pi.exported;
6545            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
6546                if (pi.readPermission != null) {
6547                    allowed = false;
6548                }
6549            }
6550            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
6551                if (pi.writePermission != null) {
6552                    allowed = false;
6553                }
6554            }
6555            if (allowed) {
6556                return -1;
6557            }
6558        }
6559
6560        /* There is a special cross user grant if:
6561         * - The target is on another user.
6562         * - Apps on the current user can access the uri without any uid permissions.
6563         * In this case, we grant a uri permission, even if the ContentProvider does not normally
6564         * grant uri permissions.
6565         */
6566        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
6567                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
6568                modeFlags, false /*without considering the uid permissions*/);
6569
6570        // Second...  is the provider allowing granting of URI permissions?
6571        if (!specialCrossUserGrant) {
6572            if (!pi.grantUriPermissions) {
6573                throw new SecurityException("Provider " + pi.packageName
6574                        + "/" + pi.name
6575                        + " does not allow granting of Uri permissions (uri "
6576                        + grantUri + ")");
6577            }
6578            if (pi.uriPermissionPatterns != null) {
6579                final int N = pi.uriPermissionPatterns.length;
6580                boolean allowed = false;
6581                for (int i=0; i<N; i++) {
6582                    if (pi.uriPermissionPatterns[i] != null
6583                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
6584                        allowed = true;
6585                        break;
6586                    }
6587                }
6588                if (!allowed) {
6589                    throw new SecurityException("Provider " + pi.packageName
6590                            + "/" + pi.name
6591                            + " does not allow granting of permission to path of Uri "
6592                            + grantUri);
6593                }
6594            }
6595        }
6596
6597        // Third...  does the caller itself have permission to access
6598        // this uri?
6599        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
6600            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6601                // Require they hold a strong enough Uri permission
6602                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
6603                    throw new SecurityException("Uid " + callingUid
6604                            + " does not have permission to uri " + grantUri);
6605                }
6606            }
6607        }
6608        return targetUid;
6609    }
6610
6611    @Override
6612    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
6613            final int modeFlags, int userId) {
6614        enforceNotIsolatedCaller("checkGrantUriPermission");
6615        synchronized(this) {
6616            return checkGrantUriPermissionLocked(callingUid, targetPkg,
6617                    new GrantUri(userId, uri, false), modeFlags, -1);
6618        }
6619    }
6620
6621    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
6622            final int modeFlags, UriPermissionOwner owner) {
6623        if (!Intent.isAccessUriMode(modeFlags)) {
6624            return;
6625        }
6626
6627        // So here we are: the caller has the assumed permission
6628        // to the uri, and the target doesn't.  Let's now give this to
6629        // the target.
6630
6631        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6632                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
6633
6634        final String authority = grantUri.uri.getAuthority();
6635        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6636        if (pi == null) {
6637            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
6638            return;
6639        }
6640
6641        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
6642            grantUri.prefix = true;
6643        }
6644        final UriPermission perm = findOrCreateUriPermissionLocked(
6645                pi.packageName, targetPkg, targetUid, grantUri);
6646        perm.grantModes(modeFlags, owner);
6647    }
6648
6649    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
6650            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
6651        if (targetPkg == null) {
6652            throw new NullPointerException("targetPkg");
6653        }
6654        int targetUid;
6655        final IPackageManager pm = AppGlobals.getPackageManager();
6656        try {
6657            targetUid = pm.getPackageUid(targetPkg, targetUserId);
6658        } catch (RemoteException ex) {
6659            return;
6660        }
6661
6662        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
6663                targetUid);
6664        if (targetUid < 0) {
6665            return;
6666        }
6667
6668        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
6669                owner);
6670    }
6671
6672    static class NeededUriGrants extends ArrayList<GrantUri> {
6673        final String targetPkg;
6674        final int targetUid;
6675        final int flags;
6676
6677        NeededUriGrants(String targetPkg, int targetUid, int flags) {
6678            this.targetPkg = targetPkg;
6679            this.targetUid = targetUid;
6680            this.flags = flags;
6681        }
6682    }
6683
6684    /**
6685     * Like checkGrantUriPermissionLocked, but takes an Intent.
6686     */
6687    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
6688            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
6689        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6690                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
6691                + " clip=" + (intent != null ? intent.getClipData() : null)
6692                + " from " + intent + "; flags=0x"
6693                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
6694
6695        if (targetPkg == null) {
6696            throw new NullPointerException("targetPkg");
6697        }
6698
6699        if (intent == null) {
6700            return null;
6701        }
6702        Uri data = intent.getData();
6703        ClipData clip = intent.getClipData();
6704        if (data == null && clip == null) {
6705            return null;
6706        }
6707        // Default userId for uris in the intent (if they don't specify it themselves)
6708        int contentUserHint = intent.getContentUserHint();
6709        if (contentUserHint == UserHandle.USER_CURRENT) {
6710            contentUserHint = UserHandle.getUserId(callingUid);
6711        }
6712        final IPackageManager pm = AppGlobals.getPackageManager();
6713        int targetUid;
6714        if (needed != null) {
6715            targetUid = needed.targetUid;
6716        } else {
6717            try {
6718                targetUid = pm.getPackageUid(targetPkg, targetUserId);
6719            } catch (RemoteException ex) {
6720                return null;
6721            }
6722            if (targetUid < 0) {
6723                if (DEBUG_URI_PERMISSION) {
6724                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
6725                            + " on user " + targetUserId);
6726                }
6727                return null;
6728            }
6729        }
6730        if (data != null) {
6731            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
6732            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6733                    targetUid);
6734            if (targetUid > 0) {
6735                if (needed == null) {
6736                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
6737                }
6738                needed.add(grantUri);
6739            }
6740        }
6741        if (clip != null) {
6742            for (int i=0; i<clip.getItemCount(); i++) {
6743                Uri uri = clip.getItemAt(i).getUri();
6744                if (uri != null) {
6745                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
6746                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
6747                            targetUid);
6748                    if (targetUid > 0) {
6749                        if (needed == null) {
6750                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
6751                        }
6752                        needed.add(grantUri);
6753                    }
6754                } else {
6755                    Intent clipIntent = clip.getItemAt(i).getIntent();
6756                    if (clipIntent != null) {
6757                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
6758                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
6759                        if (newNeeded != null) {
6760                            needed = newNeeded;
6761                        }
6762                    }
6763                }
6764            }
6765        }
6766
6767        return needed;
6768    }
6769
6770    /**
6771     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
6772     */
6773    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
6774            UriPermissionOwner owner) {
6775        if (needed != null) {
6776            for (int i=0; i<needed.size(); i++) {
6777                GrantUri grantUri = needed.get(i);
6778                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
6779                        grantUri, needed.flags, owner);
6780            }
6781        }
6782    }
6783
6784    void grantUriPermissionFromIntentLocked(int callingUid,
6785            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
6786        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
6787                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
6788        if (needed == null) {
6789            return;
6790        }
6791
6792        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
6793    }
6794
6795    @Override
6796    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
6797            final int modeFlags, int userId) {
6798        enforceNotIsolatedCaller("grantUriPermission");
6799        GrantUri grantUri = new GrantUri(userId, uri, false);
6800        synchronized(this) {
6801            final ProcessRecord r = getRecordForAppLocked(caller);
6802            if (r == null) {
6803                throw new SecurityException("Unable to find app for caller "
6804                        + caller
6805                        + " when granting permission to uri " + grantUri);
6806            }
6807            if (targetPkg == null) {
6808                throw new IllegalArgumentException("null target");
6809            }
6810            if (grantUri == null) {
6811                throw new IllegalArgumentException("null uri");
6812            }
6813
6814            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
6815                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
6816                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
6817                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
6818
6819            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
6820                    UserHandle.getUserId(r.uid));
6821        }
6822    }
6823
6824    void removeUriPermissionIfNeededLocked(UriPermission perm) {
6825        if (perm.modeFlags == 0) {
6826            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
6827                    perm.targetUid);
6828            if (perms != null) {
6829                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6830                        "Removing " + perm.targetUid + " permission to " + perm.uri);
6831
6832                perms.remove(perm.uri);
6833                if (perms.isEmpty()) {
6834                    mGrantedUriPermissions.remove(perm.targetUid);
6835                }
6836            }
6837        }
6838    }
6839
6840    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
6841        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
6842
6843        final IPackageManager pm = AppGlobals.getPackageManager();
6844        final String authority = grantUri.uri.getAuthority();
6845        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
6846        if (pi == null) {
6847            Slog.w(TAG, "No content provider found for permission revoke: "
6848                    + grantUri.toSafeString());
6849            return;
6850        }
6851
6852        // Does the caller have this permission on the URI?
6853        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
6854            // Right now, if you are not the original owner of the permission,
6855            // you are not allowed to revoke it.
6856            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
6857                throw new SecurityException("Uid " + callingUid
6858                        + " does not have permission to uri " + grantUri);
6859            //}
6860        }
6861
6862        boolean persistChanged = false;
6863
6864        // Go through all of the permissions and remove any that match.
6865        int N = mGrantedUriPermissions.size();
6866        for (int i = 0; i < N; i++) {
6867            final int targetUid = mGrantedUriPermissions.keyAt(i);
6868            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6869
6870            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6871                final UriPermission perm = it.next();
6872                if (perm.uri.sourceUserId == grantUri.sourceUserId
6873                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
6874                    if (DEBUG_URI_PERMISSION)
6875                        Slog.v(TAG,
6876                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
6877                    persistChanged |= perm.revokeModes(
6878                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6879                    if (perm.modeFlags == 0) {
6880                        it.remove();
6881                    }
6882                }
6883            }
6884
6885            if (perms.isEmpty()) {
6886                mGrantedUriPermissions.remove(targetUid);
6887                N--;
6888                i--;
6889            }
6890        }
6891
6892        if (persistChanged) {
6893            schedulePersistUriGrants();
6894        }
6895    }
6896
6897    @Override
6898    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
6899            int userId) {
6900        enforceNotIsolatedCaller("revokeUriPermission");
6901        synchronized(this) {
6902            final ProcessRecord r = getRecordForAppLocked(caller);
6903            if (r == null) {
6904                throw new SecurityException("Unable to find app for caller "
6905                        + caller
6906                        + " when revoking permission to uri " + uri);
6907            }
6908            if (uri == null) {
6909                Slog.w(TAG, "revokeUriPermission: null uri");
6910                return;
6911            }
6912
6913            if (!Intent.isAccessUriMode(modeFlags)) {
6914                return;
6915            }
6916
6917            final IPackageManager pm = AppGlobals.getPackageManager();
6918            final String authority = uri.getAuthority();
6919            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
6920            if (pi == null) {
6921                Slog.w(TAG, "No content provider found for permission revoke: "
6922                        + uri.toSafeString());
6923                return;
6924            }
6925
6926            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
6927        }
6928    }
6929
6930    /**
6931     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
6932     * given package.
6933     *
6934     * @param packageName Package name to match, or {@code null} to apply to all
6935     *            packages.
6936     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
6937     *            to all users.
6938     * @param persistable If persistable grants should be removed.
6939     */
6940    private void removeUriPermissionsForPackageLocked(
6941            String packageName, int userHandle, boolean persistable) {
6942        if (userHandle == UserHandle.USER_ALL && packageName == null) {
6943            throw new IllegalArgumentException("Must narrow by either package or user");
6944        }
6945
6946        boolean persistChanged = false;
6947
6948        int N = mGrantedUriPermissions.size();
6949        for (int i = 0; i < N; i++) {
6950            final int targetUid = mGrantedUriPermissions.keyAt(i);
6951            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
6952
6953            // Only inspect grants matching user
6954            if (userHandle == UserHandle.USER_ALL
6955                    || userHandle == UserHandle.getUserId(targetUid)) {
6956                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
6957                    final UriPermission perm = it.next();
6958
6959                    // Only inspect grants matching package
6960                    if (packageName == null || perm.sourcePkg.equals(packageName)
6961                            || perm.targetPkg.equals(packageName)) {
6962                        persistChanged |= perm.revokeModes(
6963                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
6964
6965                        // Only remove when no modes remain; any persisted grants
6966                        // will keep this alive.
6967                        if (perm.modeFlags == 0) {
6968                            it.remove();
6969                        }
6970                    }
6971                }
6972
6973                if (perms.isEmpty()) {
6974                    mGrantedUriPermissions.remove(targetUid);
6975                    N--;
6976                    i--;
6977                }
6978            }
6979        }
6980
6981        if (persistChanged) {
6982            schedulePersistUriGrants();
6983        }
6984    }
6985
6986    @Override
6987    public IBinder newUriPermissionOwner(String name) {
6988        enforceNotIsolatedCaller("newUriPermissionOwner");
6989        synchronized(this) {
6990            UriPermissionOwner owner = new UriPermissionOwner(this, name);
6991            return owner.getExternalTokenLocked();
6992        }
6993    }
6994
6995    @Override
6996    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
6997            final int modeFlags, int sourceUserId, int targetUserId) {
6998        synchronized(this) {
6999            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7000            if (owner == null) {
7001                throw new IllegalArgumentException("Unknown owner: " + token);
7002            }
7003            if (fromUid != Binder.getCallingUid()) {
7004                if (Binder.getCallingUid() != Process.myUid()) {
7005                    // Only system code can grant URI permissions on behalf
7006                    // of other users.
7007                    throw new SecurityException("nice try");
7008                }
7009            }
7010            if (targetPkg == null) {
7011                throw new IllegalArgumentException("null target");
7012            }
7013            if (uri == null) {
7014                throw new IllegalArgumentException("null uri");
7015            }
7016
7017            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7018                    modeFlags, owner, targetUserId);
7019        }
7020    }
7021
7022    @Override
7023    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7024        synchronized(this) {
7025            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7026            if (owner == null) {
7027                throw new IllegalArgumentException("Unknown owner: " + token);
7028            }
7029
7030            if (uri == null) {
7031                owner.removeUriPermissionsLocked(mode);
7032            } else {
7033                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7034            }
7035        }
7036    }
7037
7038    private void schedulePersistUriGrants() {
7039        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7040            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7041                    10 * DateUtils.SECOND_IN_MILLIS);
7042        }
7043    }
7044
7045    private void writeGrantedUriPermissions() {
7046        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7047
7048        // Snapshot permissions so we can persist without lock
7049        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7050        synchronized (this) {
7051            final int size = mGrantedUriPermissions.size();
7052            for (int i = 0; i < size; i++) {
7053                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7054                for (UriPermission perm : perms.values()) {
7055                    if (perm.persistedModeFlags != 0) {
7056                        persist.add(perm.snapshot());
7057                    }
7058                }
7059            }
7060        }
7061
7062        FileOutputStream fos = null;
7063        try {
7064            fos = mGrantFile.startWrite();
7065
7066            XmlSerializer out = new FastXmlSerializer();
7067            out.setOutput(fos, "utf-8");
7068            out.startDocument(null, true);
7069            out.startTag(null, TAG_URI_GRANTS);
7070            for (UriPermission.Snapshot perm : persist) {
7071                out.startTag(null, TAG_URI_GRANT);
7072                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7073                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7074                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7075                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7076                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7077                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7078                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7079                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7080                out.endTag(null, TAG_URI_GRANT);
7081            }
7082            out.endTag(null, TAG_URI_GRANTS);
7083            out.endDocument();
7084
7085            mGrantFile.finishWrite(fos);
7086        } catch (IOException e) {
7087            if (fos != null) {
7088                mGrantFile.failWrite(fos);
7089            }
7090        }
7091    }
7092
7093    private void readGrantedUriPermissionsLocked() {
7094        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7095
7096        final long now = System.currentTimeMillis();
7097
7098        FileInputStream fis = null;
7099        try {
7100            fis = mGrantFile.openRead();
7101            final XmlPullParser in = Xml.newPullParser();
7102            in.setInput(fis, null);
7103
7104            int type;
7105            while ((type = in.next()) != END_DOCUMENT) {
7106                final String tag = in.getName();
7107                if (type == START_TAG) {
7108                    if (TAG_URI_GRANT.equals(tag)) {
7109                        final int sourceUserId;
7110                        final int targetUserId;
7111                        final int userHandle = readIntAttribute(in,
7112                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7113                        if (userHandle != UserHandle.USER_NULL) {
7114                            // For backwards compatibility.
7115                            sourceUserId = userHandle;
7116                            targetUserId = userHandle;
7117                        } else {
7118                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7119                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7120                        }
7121                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7122                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7123                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7124                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7125                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7126                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7127
7128                        // Sanity check that provider still belongs to source package
7129                        final ProviderInfo pi = getProviderInfoLocked(
7130                                uri.getAuthority(), sourceUserId);
7131                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7132                            int targetUid = -1;
7133                            try {
7134                                targetUid = AppGlobals.getPackageManager()
7135                                        .getPackageUid(targetPkg, targetUserId);
7136                            } catch (RemoteException e) {
7137                            }
7138                            if (targetUid != -1) {
7139                                final UriPermission perm = findOrCreateUriPermissionLocked(
7140                                        sourcePkg, targetPkg, targetUid,
7141                                        new GrantUri(sourceUserId, uri, prefix));
7142                                perm.initPersistedModes(modeFlags, createdTime);
7143                            }
7144                        } else {
7145                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7146                                    + " but instead found " + pi);
7147                        }
7148                    }
7149                }
7150            }
7151        } catch (FileNotFoundException e) {
7152            // Missing grants is okay
7153        } catch (IOException e) {
7154            Log.wtf(TAG, "Failed reading Uri grants", e);
7155        } catch (XmlPullParserException e) {
7156            Log.wtf(TAG, "Failed reading Uri grants", e);
7157        } finally {
7158            IoUtils.closeQuietly(fis);
7159        }
7160    }
7161
7162    @Override
7163    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7164        enforceNotIsolatedCaller("takePersistableUriPermission");
7165
7166        Preconditions.checkFlagsArgument(modeFlags,
7167                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7168
7169        synchronized (this) {
7170            final int callingUid = Binder.getCallingUid();
7171            boolean persistChanged = false;
7172            GrantUri grantUri = new GrantUri(userId, uri, false);
7173
7174            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7175                    new GrantUri(userId, uri, false));
7176            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7177                    new GrantUri(userId, uri, true));
7178
7179            final boolean exactValid = (exactPerm != null)
7180                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7181            final boolean prefixValid = (prefixPerm != null)
7182                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7183
7184            if (!(exactValid || prefixValid)) {
7185                throw new SecurityException("No persistable permission grants found for UID "
7186                        + callingUid + " and Uri " + grantUri.toSafeString());
7187            }
7188
7189            if (exactValid) {
7190                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7191            }
7192            if (prefixValid) {
7193                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7194            }
7195
7196            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7197
7198            if (persistChanged) {
7199                schedulePersistUriGrants();
7200            }
7201        }
7202    }
7203
7204    @Override
7205    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7206        enforceNotIsolatedCaller("releasePersistableUriPermission");
7207
7208        Preconditions.checkFlagsArgument(modeFlags,
7209                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7210
7211        synchronized (this) {
7212            final int callingUid = Binder.getCallingUid();
7213            boolean persistChanged = false;
7214
7215            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7216                    new GrantUri(userId, uri, false));
7217            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7218                    new GrantUri(userId, uri, true));
7219            if (exactPerm == null && prefixPerm == null) {
7220                throw new SecurityException("No permission grants found for UID " + callingUid
7221                        + " and Uri " + uri.toSafeString());
7222            }
7223
7224            if (exactPerm != null) {
7225                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7226                removeUriPermissionIfNeededLocked(exactPerm);
7227            }
7228            if (prefixPerm != null) {
7229                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7230                removeUriPermissionIfNeededLocked(prefixPerm);
7231            }
7232
7233            if (persistChanged) {
7234                schedulePersistUriGrants();
7235            }
7236        }
7237    }
7238
7239    /**
7240     * Prune any older {@link UriPermission} for the given UID until outstanding
7241     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7242     *
7243     * @return if any mutations occured that require persisting.
7244     */
7245    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7246        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7247        if (perms == null) return false;
7248        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7249
7250        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7251        for (UriPermission perm : perms.values()) {
7252            if (perm.persistedModeFlags != 0) {
7253                persisted.add(perm);
7254            }
7255        }
7256
7257        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7258        if (trimCount <= 0) return false;
7259
7260        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7261        for (int i = 0; i < trimCount; i++) {
7262            final UriPermission perm = persisted.get(i);
7263
7264            if (DEBUG_URI_PERMISSION) {
7265                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7266            }
7267
7268            perm.releasePersistableModes(~0);
7269            removeUriPermissionIfNeededLocked(perm);
7270        }
7271
7272        return true;
7273    }
7274
7275    @Override
7276    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7277            String packageName, boolean incoming) {
7278        enforceNotIsolatedCaller("getPersistedUriPermissions");
7279        Preconditions.checkNotNull(packageName, "packageName");
7280
7281        final int callingUid = Binder.getCallingUid();
7282        final IPackageManager pm = AppGlobals.getPackageManager();
7283        try {
7284            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7285            if (packageUid != callingUid) {
7286                throw new SecurityException(
7287                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7288            }
7289        } catch (RemoteException e) {
7290            throw new SecurityException("Failed to verify package name ownership");
7291        }
7292
7293        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7294        synchronized (this) {
7295            if (incoming) {
7296                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7297                        callingUid);
7298                if (perms == null) {
7299                    Slog.w(TAG, "No permission grants found for " + packageName);
7300                } else {
7301                    for (UriPermission perm : perms.values()) {
7302                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7303                            result.add(perm.buildPersistedPublicApiObject());
7304                        }
7305                    }
7306                }
7307            } else {
7308                final int size = mGrantedUriPermissions.size();
7309                for (int i = 0; i < size; i++) {
7310                    final ArrayMap<GrantUri, UriPermission> perms =
7311                            mGrantedUriPermissions.valueAt(i);
7312                    for (UriPermission perm : perms.values()) {
7313                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7314                            result.add(perm.buildPersistedPublicApiObject());
7315                        }
7316                    }
7317                }
7318            }
7319        }
7320        return new ParceledListSlice<android.content.UriPermission>(result);
7321    }
7322
7323    @Override
7324    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7325        synchronized (this) {
7326            ProcessRecord app =
7327                who != null ? getRecordForAppLocked(who) : null;
7328            if (app == null) return;
7329
7330            Message msg = Message.obtain();
7331            msg.what = WAIT_FOR_DEBUGGER_MSG;
7332            msg.obj = app;
7333            msg.arg1 = waiting ? 1 : 0;
7334            mHandler.sendMessage(msg);
7335        }
7336    }
7337
7338    @Override
7339    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7340        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7341        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7342        outInfo.availMem = Process.getFreeMemory();
7343        outInfo.totalMem = Process.getTotalMemory();
7344        outInfo.threshold = homeAppMem;
7345        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7346        outInfo.hiddenAppThreshold = cachedAppMem;
7347        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7348                ProcessList.SERVICE_ADJ);
7349        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7350                ProcessList.VISIBLE_APP_ADJ);
7351        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7352                ProcessList.FOREGROUND_APP_ADJ);
7353    }
7354
7355    // =========================================================
7356    // TASK MANAGEMENT
7357    // =========================================================
7358
7359    @Override
7360    public List<IAppTask> getAppTasks() {
7361        final PackageManager pm = mContext.getPackageManager();
7362        int callingUid = Binder.getCallingUid();
7363        long ident = Binder.clearCallingIdentity();
7364
7365        // Compose the list of packages for this id to test against
7366        HashSet<String> packages = new HashSet<String>();
7367        String[] uidPackages = pm.getPackagesForUid(callingUid);
7368        for (int i = 0; i < uidPackages.length; i++) {
7369            packages.add(uidPackages[i]);
7370        }
7371
7372        synchronized(this) {
7373            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7374            try {
7375                if (localLOGV) Slog.v(TAG, "getAppTasks");
7376
7377                final int N = mRecentTasks.size();
7378                for (int i = 0; i < N; i++) {
7379                    TaskRecord tr = mRecentTasks.get(i);
7380                    // Skip tasks that are not created by the caller
7381                    if (packages.contains(tr.getBaseIntent().getComponent().getPackageName())) {
7382                        ActivityManager.RecentTaskInfo taskInfo =
7383                                createRecentTaskInfoFromTaskRecord(tr);
7384                        AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7385                        list.add(taskImpl);
7386                    }
7387                }
7388            } finally {
7389                Binder.restoreCallingIdentity(ident);
7390            }
7391            return list;
7392        }
7393    }
7394
7395    @Override
7396    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7397        final int callingUid = Binder.getCallingUid();
7398        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7399
7400        synchronized(this) {
7401            if (localLOGV) Slog.v(
7402                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7403
7404            final boolean allowed = checkCallingPermission(
7405                    android.Manifest.permission.GET_TASKS)
7406                    == PackageManager.PERMISSION_GRANTED;
7407            if (!allowed) {
7408                Slog.w(TAG, "getTasks: caller " + callingUid
7409                        + " does not hold GET_TASKS; limiting output");
7410            }
7411
7412            // TODO: Improve with MRU list from all ActivityStacks.
7413            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7414        }
7415
7416        return list;
7417    }
7418
7419    TaskRecord getMostRecentTask() {
7420        return mRecentTasks.get(0);
7421    }
7422
7423    /**
7424     * Creates a new RecentTaskInfo from a TaskRecord.
7425     */
7426    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
7427        // Update the task description to reflect any changes in the task stack
7428        tr.updateTaskDescription();
7429
7430        // Compose the recent task info
7431        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
7432        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
7433        rti.persistentId = tr.taskId;
7434        rti.baseIntent = new Intent(tr.getBaseIntent());
7435        rti.origActivity = tr.origActivity;
7436        rti.description = tr.lastDescription;
7437        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
7438        rti.userId = tr.userId;
7439        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
7440        rti.firstActiveTime = tr.firstActiveTime;
7441        rti.lastActiveTime = tr.lastActiveTime;
7442        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
7443        return rti;
7444    }
7445
7446    @Override
7447    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
7448        final int callingUid = Binder.getCallingUid();
7449        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7450                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
7451
7452        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
7453        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
7454        synchronized (this) {
7455            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
7456                    == PackageManager.PERMISSION_GRANTED;
7457            if (!allowed) {
7458                Slog.w(TAG, "getRecentTasks: caller " + callingUid
7459                        + " does not hold GET_TASKS; limiting output");
7460            }
7461            final boolean detailed = checkCallingPermission(
7462                    android.Manifest.permission.GET_DETAILED_TASKS)
7463                    == PackageManager.PERMISSION_GRANTED;
7464
7465            IPackageManager pm = AppGlobals.getPackageManager();
7466
7467            final int N = mRecentTasks.size();
7468            ArrayList<ActivityManager.RecentTaskInfo> res
7469                    = new ArrayList<ActivityManager.RecentTaskInfo>(
7470                            maxNum < N ? maxNum : N);
7471
7472            final Set<Integer> includedUsers;
7473            if (includeProfiles) {
7474                includedUsers = getProfileIdsLocked(userId);
7475            } else {
7476                includedUsers = new HashSet<Integer>();
7477            }
7478            includedUsers.add(Integer.valueOf(userId));
7479
7480            // Regroup affiliated tasks together.
7481            for (int i = 0; i < N; ) {
7482                TaskRecord task = mRecentTasks.remove(i);
7483                if (mTmpRecents.contains(task)) {
7484                    continue;
7485                }
7486                int affiliatedTaskId = task.mAffiliatedTaskId;
7487                while (true) {
7488                    TaskRecord next = task.mNextAffiliate;
7489                    if (next == null) {
7490                        break;
7491                    }
7492                    if (next.mAffiliatedTaskId != affiliatedTaskId) {
7493                        Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
7494                                next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
7495                        task.setNextAffiliate(null);
7496                        if (next.mPrevAffiliate == task) {
7497                            next.setPrevAffiliate(null);
7498                        }
7499                        break;
7500                    }
7501                    if (next.mPrevAffiliate != task) {
7502                        Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
7503                                next.mPrevAffiliate + " task=" + task);
7504                        next.setPrevAffiliate(null);
7505                        break;
7506                    }
7507                    if (!mRecentTasks.contains(next)) {
7508                        Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
7509                        task.setNextAffiliate(null);
7510                        if (next.mPrevAffiliate == task) {
7511                            next.setPrevAffiliate(null);
7512                        }
7513                        break;
7514                    }
7515                    task = next;
7516                }
7517                // task is now the end of the list
7518                do {
7519                    mRecentTasks.remove(task);
7520                    mRecentTasks.add(i++, task);
7521                    mTmpRecents.add(task);
7522                } while ((task = task.mPrevAffiliate) != null);
7523            }
7524            mTmpRecents.clear();
7525            // mRecentTasks is now in sorted, affiliated order.
7526
7527            for (int i=0; i<N && maxNum > 0; i++) {
7528                TaskRecord tr = mRecentTasks.get(i);
7529                // Only add calling user or related users recent tasks
7530                if (!includedUsers.contains(Integer.valueOf(tr.userId))) continue;
7531
7532                // Return the entry if desired by the caller.  We always return
7533                // the first entry, because callers always expect this to be the
7534                // foreground app.  We may filter others if the caller has
7535                // not supplied RECENT_WITH_EXCLUDED and there is some reason
7536                // we should exclude the entry.
7537
7538                if (i == 0
7539                        || withExcluded
7540                        || (tr.intent == null)
7541                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
7542                                == 0)) {
7543                    if (!allowed) {
7544                        // If the caller doesn't have the GET_TASKS permission, then only
7545                        // allow them to see a small subset of tasks -- their own and home.
7546                        if (!tr.isHomeTask() && tr.creatorUid != callingUid) {
7547                            continue;
7548                        }
7549                    }
7550                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
7551                        // Don't include auto remove tasks that are finished or finishing.
7552                        continue;
7553                    }
7554
7555                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
7556                    if (!detailed) {
7557                        rti.baseIntent.replaceExtras((Bundle)null);
7558                    }
7559
7560                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
7561                        // Check whether this activity is currently available.
7562                        try {
7563                            if (rti.origActivity != null) {
7564                                if (pm.getActivityInfo(rti.origActivity, 0, userId)
7565                                        == null) {
7566                                    continue;
7567                                }
7568                            } else if (rti.baseIntent != null) {
7569                                if (pm.queryIntentActivities(rti.baseIntent,
7570                                        null, 0, userId) == null) {
7571                                    continue;
7572                                }
7573                            }
7574                        } catch (RemoteException e) {
7575                            // Will never happen.
7576                        }
7577                    }
7578
7579                    res.add(rti);
7580                    maxNum--;
7581                }
7582            }
7583            return res;
7584        }
7585    }
7586
7587    private TaskRecord recentTaskForIdLocked(int id) {
7588        final int N = mRecentTasks.size();
7589            for (int i=0; i<N; i++) {
7590                TaskRecord tr = mRecentTasks.get(i);
7591                if (tr.taskId == id) {
7592                    return tr;
7593                }
7594            }
7595            return null;
7596    }
7597
7598    @Override
7599    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
7600        synchronized (this) {
7601            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
7602                    "getTaskThumbnail()");
7603            TaskRecord tr = recentTaskForIdLocked(id);
7604            if (tr != null) {
7605                return tr.getTaskThumbnailLocked();
7606            }
7607        }
7608        return null;
7609    }
7610
7611    @Override
7612    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
7613        synchronized (this) {
7614            ActivityRecord r = ActivityRecord.isInStackLocked(token);
7615            if (r != null) {
7616                r.taskDescription = td;
7617                r.task.updateTaskDescription();
7618            }
7619        }
7620    }
7621
7622    private void killUnneededProcessLocked(ProcessRecord pr, String reason) {
7623        if (!pr.killedByAm) {
7624            Slog.i(TAG, "Killing " + pr.toShortString() + " (adj " + pr.setAdj + "): " + reason);
7625            EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
7626                    pr.processName, pr.setAdj, reason);
7627            pr.killedByAm = true;
7628            Process.killProcessQuiet(pr.pid);
7629            Process.killProcessGroup(pr.info.uid, pr.pid);
7630        }
7631    }
7632
7633    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
7634        tr.disposeThumbnail();
7635        mRecentTasks.remove(tr);
7636        tr.closeRecentsChain();
7637        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
7638        Intent baseIntent = new Intent(
7639                tr.intent != null ? tr.intent : tr.affinityIntent);
7640        ComponentName component = baseIntent.getComponent();
7641        if (component == null) {
7642            Slog.w(TAG, "Now component for base intent of task: " + tr);
7643            return;
7644        }
7645
7646        // Find any running services associated with this app.
7647        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
7648
7649        if (killProcesses) {
7650            // Find any running processes associated with this app.
7651            final String pkg = component.getPackageName();
7652            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
7653            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
7654            for (int i=0; i<pmap.size(); i++) {
7655                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
7656                for (int j=0; j<uids.size(); j++) {
7657                    ProcessRecord proc = uids.valueAt(j);
7658                    if (proc.userId != tr.userId) {
7659                        continue;
7660                    }
7661                    if (!proc.pkgList.containsKey(pkg)) {
7662                        continue;
7663                    }
7664                    procs.add(proc);
7665                }
7666            }
7667
7668            // Kill the running processes.
7669            for (int i=0; i<procs.size(); i++) {
7670                ProcessRecord pr = procs.get(i);
7671                if (pr == mHomeProcess) {
7672                    // Don't kill the home process along with tasks from the same package.
7673                    continue;
7674                }
7675                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
7676                    killUnneededProcessLocked(pr, "remove task");
7677                } else {
7678                    pr.waitingToKill = "remove task";
7679                }
7680            }
7681        }
7682    }
7683
7684    /**
7685     * Removes the task with the specified task id.
7686     *
7687     * @param taskId Identifier of the task to be removed.
7688     * @param flags Additional operational flags.  May be 0 or
7689     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
7690     * @return Returns true if the given task was found and removed.
7691     */
7692    private boolean removeTaskByIdLocked(int taskId, int flags) {
7693        TaskRecord tr = recentTaskForIdLocked(taskId);
7694        if (tr != null) {
7695            tr.removeTaskActivitiesLocked();
7696            cleanUpRemovedTaskLocked(tr, flags);
7697            if (tr.isPersistable) {
7698                notifyTaskPersisterLocked(null, true);
7699            }
7700            return true;
7701        }
7702        return false;
7703    }
7704
7705    @Override
7706    public boolean removeTask(int taskId, int flags) {
7707        synchronized (this) {
7708            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
7709                    "removeTask()");
7710            long ident = Binder.clearCallingIdentity();
7711            try {
7712                return removeTaskByIdLocked(taskId, flags);
7713            } finally {
7714                Binder.restoreCallingIdentity(ident);
7715            }
7716        }
7717    }
7718
7719    /**
7720     * TODO: Add mController hook
7721     */
7722    @Override
7723    public void moveTaskToFront(int taskId, int flags, Bundle options) {
7724        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7725                "moveTaskToFront()");
7726
7727        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
7728        synchronized(this) {
7729            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7730                    Binder.getCallingUid(), "Task to front")) {
7731                ActivityOptions.abort(options);
7732                return;
7733            }
7734            final long origId = Binder.clearCallingIdentity();
7735            try {
7736                final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
7737                if (task == null) {
7738                    return;
7739                }
7740                if (mStackSupervisor.isLockTaskModeViolation(task)) {
7741                    mStackSupervisor.showLockTaskToast();
7742                    Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
7743                    return;
7744                }
7745                final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
7746                if (prev != null && prev.isRecentsActivity()) {
7747                    task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
7748                }
7749                mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
7750            } finally {
7751                Binder.restoreCallingIdentity(origId);
7752            }
7753            ActivityOptions.abort(options);
7754        }
7755    }
7756
7757    @Override
7758    public void moveTaskToBack(int taskId) {
7759        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7760                "moveTaskToBack()");
7761
7762        synchronized(this) {
7763            TaskRecord tr = recentTaskForIdLocked(taskId);
7764            if (tr != null) {
7765                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
7766                ActivityStack stack = tr.stack;
7767                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
7768                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7769                            Binder.getCallingUid(), "Task to back")) {
7770                        return;
7771                    }
7772                }
7773                final long origId = Binder.clearCallingIdentity();
7774                try {
7775                    stack.moveTaskToBackLocked(taskId, null);
7776                } finally {
7777                    Binder.restoreCallingIdentity(origId);
7778                }
7779            }
7780        }
7781    }
7782
7783    /**
7784     * Moves an activity, and all of the other activities within the same task, to the bottom
7785     * of the history stack.  The activity's order within the task is unchanged.
7786     *
7787     * @param token A reference to the activity we wish to move
7788     * @param nonRoot If false then this only works if the activity is the root
7789     *                of a task; if true it will work for any activity in a task.
7790     * @return Returns true if the move completed, false if not.
7791     */
7792    @Override
7793    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
7794        enforceNotIsolatedCaller("moveActivityTaskToBack");
7795        synchronized(this) {
7796            final long origId = Binder.clearCallingIdentity();
7797            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
7798            if (taskId >= 0) {
7799                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
7800            }
7801            Binder.restoreCallingIdentity(origId);
7802        }
7803        return false;
7804    }
7805
7806    @Override
7807    public void moveTaskBackwards(int task) {
7808        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
7809                "moveTaskBackwards()");
7810
7811        synchronized(this) {
7812            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
7813                    Binder.getCallingUid(), "Task backwards")) {
7814                return;
7815            }
7816            final long origId = Binder.clearCallingIdentity();
7817            moveTaskBackwardsLocked(task);
7818            Binder.restoreCallingIdentity(origId);
7819        }
7820    }
7821
7822    private final void moveTaskBackwardsLocked(int task) {
7823        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
7824    }
7825
7826    @Override
7827    public IBinder getHomeActivityToken() throws RemoteException {
7828        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7829                "getHomeActivityToken()");
7830        synchronized (this) {
7831            return mStackSupervisor.getHomeActivityToken();
7832        }
7833    }
7834
7835    @Override
7836    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
7837            IActivityContainerCallback callback) throws RemoteException {
7838        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7839                "createActivityContainer()");
7840        synchronized (this) {
7841            if (parentActivityToken == null) {
7842                throw new IllegalArgumentException("parent token must not be null");
7843            }
7844            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
7845            if (r == null) {
7846                return null;
7847            }
7848            if (callback == null) {
7849                throw new IllegalArgumentException("callback must not be null");
7850            }
7851            return mStackSupervisor.createActivityContainer(r, callback);
7852        }
7853    }
7854
7855    @Override
7856    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
7857        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7858                "deleteActivityContainer()");
7859        synchronized (this) {
7860            mStackSupervisor.deleteActivityContainer(container);
7861        }
7862    }
7863
7864    @Override
7865    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
7866            throws RemoteException {
7867        synchronized (this) {
7868            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
7869            if (stack != null) {
7870                return stack.mActivityContainer;
7871            }
7872            return null;
7873        }
7874    }
7875
7876    @Override
7877    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
7878        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7879                "moveTaskToStack()");
7880        if (stackId == HOME_STACK_ID) {
7881            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
7882                    new RuntimeException("here").fillInStackTrace());
7883        }
7884        synchronized (this) {
7885            long ident = Binder.clearCallingIdentity();
7886            try {
7887                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
7888                        + stackId + " toTop=" + toTop);
7889                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
7890            } finally {
7891                Binder.restoreCallingIdentity(ident);
7892            }
7893        }
7894    }
7895
7896    @Override
7897    public void resizeStack(int stackBoxId, Rect bounds) {
7898        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7899                "resizeStackBox()");
7900        long ident = Binder.clearCallingIdentity();
7901        try {
7902            mWindowManager.resizeStack(stackBoxId, bounds);
7903        } finally {
7904            Binder.restoreCallingIdentity(ident);
7905        }
7906    }
7907
7908    @Override
7909    public List<StackInfo> getAllStackInfos() {
7910        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7911                "getAllStackInfos()");
7912        long ident = Binder.clearCallingIdentity();
7913        try {
7914            synchronized (this) {
7915                return mStackSupervisor.getAllStackInfosLocked();
7916            }
7917        } finally {
7918            Binder.restoreCallingIdentity(ident);
7919        }
7920    }
7921
7922    @Override
7923    public StackInfo getStackInfo(int stackId) {
7924        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7925                "getStackInfo()");
7926        long ident = Binder.clearCallingIdentity();
7927        try {
7928            synchronized (this) {
7929                return mStackSupervisor.getStackInfoLocked(stackId);
7930            }
7931        } finally {
7932            Binder.restoreCallingIdentity(ident);
7933        }
7934    }
7935
7936    @Override
7937    public boolean isInHomeStack(int taskId) {
7938        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
7939                "getStackInfo()");
7940        long ident = Binder.clearCallingIdentity();
7941        try {
7942            synchronized (this) {
7943                TaskRecord tr = recentTaskForIdLocked(taskId);
7944                return tr != null && tr.stack != null && tr.stack.isHomeStack();
7945            }
7946        } finally {
7947            Binder.restoreCallingIdentity(ident);
7948        }
7949    }
7950
7951    @Override
7952    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
7953        synchronized(this) {
7954            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
7955        }
7956    }
7957
7958    private boolean isLockTaskAuthorized(String pkg) {
7959        final DevicePolicyManager dpm = (DevicePolicyManager)
7960                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
7961        try {
7962            int uid = mContext.getPackageManager().getPackageUid(pkg,
7963                    Binder.getCallingUserHandle().getIdentifier());
7964            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
7965        } catch (NameNotFoundException e) {
7966            return false;
7967        }
7968    }
7969
7970    void startLockTaskMode(TaskRecord task) {
7971        final String pkg;
7972        synchronized (this) {
7973            pkg = task.intent.getComponent().getPackageName();
7974        }
7975        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
7976        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
7977            final TaskRecord taskRecord = task;
7978            mHandler.post(new Runnable() {
7979                @Override
7980                public void run() {
7981                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
7982                }
7983            });
7984            return;
7985        }
7986        long ident = Binder.clearCallingIdentity();
7987        try {
7988            synchronized (this) {
7989                // Since we lost lock on task, make sure it is still there.
7990                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
7991                if (task != null) {
7992                    if (!isSystemInitiated
7993                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
7994                        throw new IllegalArgumentException("Invalid task, not in foreground");
7995                    }
7996                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
7997                }
7998            }
7999        } finally {
8000            Binder.restoreCallingIdentity(ident);
8001        }
8002    }
8003
8004    @Override
8005    public void startLockTaskMode(int taskId) {
8006        final TaskRecord task;
8007        long ident = Binder.clearCallingIdentity();
8008        try {
8009            synchronized (this) {
8010                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8011            }
8012        } finally {
8013            Binder.restoreCallingIdentity(ident);
8014        }
8015        if (task != null) {
8016            startLockTaskMode(task);
8017        }
8018    }
8019
8020    @Override
8021    public void startLockTaskMode(IBinder token) {
8022        final TaskRecord task;
8023        long ident = Binder.clearCallingIdentity();
8024        try {
8025            synchronized (this) {
8026                final ActivityRecord r = ActivityRecord.forToken(token);
8027                if (r == null) {
8028                    return;
8029                }
8030                task = r.task;
8031            }
8032        } finally {
8033            Binder.restoreCallingIdentity(ident);
8034        }
8035        if (task != null) {
8036            startLockTaskMode(task);
8037        }
8038    }
8039
8040    @Override
8041    public void startLockTaskModeOnCurrent() throws RemoteException {
8042        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8043        ActivityRecord r = null;
8044        synchronized (this) {
8045            r = mStackSupervisor.topRunningActivityLocked();
8046        }
8047        startLockTaskMode(r.task);
8048    }
8049
8050    @Override
8051    public void stopLockTaskMode() {
8052        // Verify that the user matches the package of the intent for the TaskRecord
8053        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8054        // and stopLockTaskMode.
8055        final int callingUid = Binder.getCallingUid();
8056        if (callingUid != Process.SYSTEM_UID) {
8057            try {
8058                String pkg =
8059                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8060                int uid = mContext.getPackageManager().getPackageUid(pkg,
8061                        Binder.getCallingUserHandle().getIdentifier());
8062                if (uid != callingUid) {
8063                    throw new SecurityException("Invalid uid, expected " + uid);
8064                }
8065            } catch (NameNotFoundException e) {
8066                Log.d(TAG, "stopLockTaskMode " + e);
8067                return;
8068            }
8069        }
8070        long ident = Binder.clearCallingIdentity();
8071        try {
8072            Log.d(TAG, "stopLockTaskMode");
8073            // Stop lock task
8074            synchronized (this) {
8075                mStackSupervisor.setLockTaskModeLocked(null, false);
8076            }
8077        } finally {
8078            Binder.restoreCallingIdentity(ident);
8079        }
8080    }
8081
8082    @Override
8083    public void stopLockTaskModeOnCurrent() throws RemoteException {
8084        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8085        long ident = Binder.clearCallingIdentity();
8086        try {
8087            stopLockTaskMode();
8088        } finally {
8089            Binder.restoreCallingIdentity(ident);
8090        }
8091    }
8092
8093    @Override
8094    public boolean isInLockTaskMode() {
8095        synchronized (this) {
8096            return mStackSupervisor.isInLockTaskMode();
8097        }
8098    }
8099
8100    // =========================================================
8101    // CONTENT PROVIDERS
8102    // =========================================================
8103
8104    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8105        List<ProviderInfo> providers = null;
8106        try {
8107            providers = AppGlobals.getPackageManager().
8108                queryContentProviders(app.processName, app.uid,
8109                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8110        } catch (RemoteException ex) {
8111        }
8112        if (DEBUG_MU)
8113            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8114        int userId = app.userId;
8115        if (providers != null) {
8116            int N = providers.size();
8117            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8118            for (int i=0; i<N; i++) {
8119                ProviderInfo cpi =
8120                    (ProviderInfo)providers.get(i);
8121                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8122                        cpi.name, cpi.flags);
8123                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8124                    // This is a singleton provider, but a user besides the
8125                    // default user is asking to initialize a process it runs
8126                    // in...  well, no, it doesn't actually run in this process,
8127                    // it runs in the process of the default user.  Get rid of it.
8128                    providers.remove(i);
8129                    N--;
8130                    i--;
8131                    continue;
8132                }
8133
8134                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8135                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8136                if (cpr == null) {
8137                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8138                    mProviderMap.putProviderByClass(comp, cpr);
8139                }
8140                if (DEBUG_MU)
8141                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8142                app.pubProviders.put(cpi.name, cpr);
8143                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8144                    // Don't add this if it is a platform component that is marked
8145                    // to run in multiple processes, because this is actually
8146                    // part of the framework so doesn't make sense to track as a
8147                    // separate apk in the process.
8148                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8149                            mProcessStats);
8150                }
8151                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8152            }
8153        }
8154        return providers;
8155    }
8156
8157    /**
8158     * Check if {@link ProcessRecord} has a possible chance at accessing the
8159     * given {@link ProviderInfo}. Final permission checking is always done
8160     * in {@link ContentProvider}.
8161     */
8162    private final String checkContentProviderPermissionLocked(
8163            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8164        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8165        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8166        boolean checkedGrants = false;
8167        if (checkUser) {
8168            // Looking for cross-user grants before enforcing the typical cross-users permissions
8169            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8170            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8171                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8172                    return null;
8173                }
8174                checkedGrants = true;
8175            }
8176            userId = handleIncomingUser(callingPid, callingUid, userId,
8177                    false, ALLOW_NON_FULL,
8178                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8179            if (userId != tmpTargetUserId) {
8180                // When we actually went to determine the final targer user ID, this ended
8181                // up different than our initial check for the authority.  This is because
8182                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8183                // SELF.  So we need to re-check the grants again.
8184                checkedGrants = false;
8185            }
8186        }
8187        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8188                cpi.applicationInfo.uid, cpi.exported)
8189                == PackageManager.PERMISSION_GRANTED) {
8190            return null;
8191        }
8192        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8193                cpi.applicationInfo.uid, cpi.exported)
8194                == PackageManager.PERMISSION_GRANTED) {
8195            return null;
8196        }
8197
8198        PathPermission[] pps = cpi.pathPermissions;
8199        if (pps != null) {
8200            int i = pps.length;
8201            while (i > 0) {
8202                i--;
8203                PathPermission pp = pps[i];
8204                String pprperm = pp.getReadPermission();
8205                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8206                        cpi.applicationInfo.uid, cpi.exported)
8207                        == PackageManager.PERMISSION_GRANTED) {
8208                    return null;
8209                }
8210                String ppwperm = pp.getWritePermission();
8211                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8212                        cpi.applicationInfo.uid, cpi.exported)
8213                        == PackageManager.PERMISSION_GRANTED) {
8214                    return null;
8215                }
8216            }
8217        }
8218        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8219            return null;
8220        }
8221
8222        String msg;
8223        if (!cpi.exported) {
8224            msg = "Permission Denial: opening provider " + cpi.name
8225                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8226                    + ", uid=" + callingUid + ") that is not exported from uid "
8227                    + cpi.applicationInfo.uid;
8228        } else {
8229            msg = "Permission Denial: opening provider " + cpi.name
8230                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8231                    + ", uid=" + callingUid + ") requires "
8232                    + cpi.readPermission + " or " + cpi.writePermission;
8233        }
8234        Slog.w(TAG, msg);
8235        return msg;
8236    }
8237
8238    /**
8239     * Returns if the ContentProvider has granted a uri to callingUid
8240     */
8241    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8242        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8243        if (perms != null) {
8244            for (int i=perms.size()-1; i>=0; i--) {
8245                GrantUri grantUri = perms.keyAt(i);
8246                if (grantUri.sourceUserId == userId || !checkUser) {
8247                    if (matchesProvider(grantUri.uri, cpi)) {
8248                        return true;
8249                    }
8250                }
8251            }
8252        }
8253        return false;
8254    }
8255
8256    /**
8257     * Returns true if the uri authority is one of the authorities specified in the provider.
8258     */
8259    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8260        String uriAuth = uri.getAuthority();
8261        String cpiAuth = cpi.authority;
8262        if (cpiAuth.indexOf(';') == -1) {
8263            return cpiAuth.equals(uriAuth);
8264        }
8265        String[] cpiAuths = cpiAuth.split(";");
8266        int length = cpiAuths.length;
8267        for (int i = 0; i < length; i++) {
8268            if (cpiAuths[i].equals(uriAuth)) return true;
8269        }
8270        return false;
8271    }
8272
8273    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8274            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8275        if (r != null) {
8276            for (int i=0; i<r.conProviders.size(); i++) {
8277                ContentProviderConnection conn = r.conProviders.get(i);
8278                if (conn.provider == cpr) {
8279                    if (DEBUG_PROVIDER) Slog.v(TAG,
8280                            "Adding provider requested by "
8281                            + r.processName + " from process "
8282                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8283                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8284                    if (stable) {
8285                        conn.stableCount++;
8286                        conn.numStableIncs++;
8287                    } else {
8288                        conn.unstableCount++;
8289                        conn.numUnstableIncs++;
8290                    }
8291                    return conn;
8292                }
8293            }
8294            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8295            if (stable) {
8296                conn.stableCount = 1;
8297                conn.numStableIncs = 1;
8298            } else {
8299                conn.unstableCount = 1;
8300                conn.numUnstableIncs = 1;
8301            }
8302            cpr.connections.add(conn);
8303            r.conProviders.add(conn);
8304            return conn;
8305        }
8306        cpr.addExternalProcessHandleLocked(externalProcessToken);
8307        return null;
8308    }
8309
8310    boolean decProviderCountLocked(ContentProviderConnection conn,
8311            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8312        if (conn != null) {
8313            cpr = conn.provider;
8314            if (DEBUG_PROVIDER) Slog.v(TAG,
8315                    "Removing provider requested by "
8316                    + conn.client.processName + " from process "
8317                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8318                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8319            if (stable) {
8320                conn.stableCount--;
8321            } else {
8322                conn.unstableCount--;
8323            }
8324            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8325                cpr.connections.remove(conn);
8326                conn.client.conProviders.remove(conn);
8327                return true;
8328            }
8329            return false;
8330        }
8331        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8332        return false;
8333    }
8334
8335    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8336            String name, IBinder token, boolean stable, int userId) {
8337        ContentProviderRecord cpr;
8338        ContentProviderConnection conn = null;
8339        ProviderInfo cpi = null;
8340
8341        synchronized(this) {
8342            ProcessRecord r = null;
8343            if (caller != null) {
8344                r = getRecordForAppLocked(caller);
8345                if (r == null) {
8346                    throw new SecurityException(
8347                            "Unable to find app for caller " + caller
8348                          + " (pid=" + Binder.getCallingPid()
8349                          + ") when getting content provider " + name);
8350                }
8351            }
8352
8353            boolean checkCrossUser = true;
8354
8355            // First check if this content provider has been published...
8356            cpr = mProviderMap.getProviderByName(name, userId);
8357            // If that didn't work, check if it exists for user 0 and then
8358            // verify that it's a singleton provider before using it.
8359            if (cpr == null && userId != UserHandle.USER_OWNER) {
8360                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8361                if (cpr != null) {
8362                    cpi = cpr.info;
8363                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8364                            cpi.name, cpi.flags)
8365                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8366                        userId = UserHandle.USER_OWNER;
8367                        checkCrossUser = false;
8368                    } else {
8369                        cpr = null;
8370                        cpi = null;
8371                    }
8372                }
8373            }
8374
8375            boolean providerRunning = cpr != null;
8376            if (providerRunning) {
8377                cpi = cpr.info;
8378                String msg;
8379                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
8380                        != null) {
8381                    throw new SecurityException(msg);
8382                }
8383
8384                if (r != null && cpr.canRunHere(r)) {
8385                    // This provider has been published or is in the process
8386                    // of being published...  but it is also allowed to run
8387                    // in the caller's process, so don't make a connection
8388                    // and just let the caller instantiate its own instance.
8389                    ContentProviderHolder holder = cpr.newHolder(null);
8390                    // don't give caller the provider object, it needs
8391                    // to make its own.
8392                    holder.provider = null;
8393                    return holder;
8394                }
8395
8396                final long origId = Binder.clearCallingIdentity();
8397
8398                // In this case the provider instance already exists, so we can
8399                // return it right away.
8400                conn = incProviderCountLocked(r, cpr, token, stable);
8401                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
8402                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
8403                        // If this is a perceptible app accessing the provider,
8404                        // make sure to count it as being accessed and thus
8405                        // back up on the LRU list.  This is good because
8406                        // content providers are often expensive to start.
8407                        updateLruProcessLocked(cpr.proc, false, null);
8408                    }
8409                }
8410
8411                if (cpr.proc != null) {
8412                    if (false) {
8413                        if (cpr.name.flattenToShortString().equals(
8414                                "com.android.providers.calendar/.CalendarProvider2")) {
8415                            Slog.v(TAG, "****************** KILLING "
8416                                + cpr.name.flattenToShortString());
8417                            Process.killProcess(cpr.proc.pid);
8418                        }
8419                    }
8420                    boolean success = updateOomAdjLocked(cpr.proc);
8421                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
8422                    // NOTE: there is still a race here where a signal could be
8423                    // pending on the process even though we managed to update its
8424                    // adj level.  Not sure what to do about this, but at least
8425                    // the race is now smaller.
8426                    if (!success) {
8427                        // Uh oh...  it looks like the provider's process
8428                        // has been killed on us.  We need to wait for a new
8429                        // process to be started, and make sure its death
8430                        // doesn't kill our process.
8431                        Slog.i(TAG,
8432                                "Existing provider " + cpr.name.flattenToShortString()
8433                                + " is crashing; detaching " + r);
8434                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
8435                        appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
8436                        if (!lastRef) {
8437                            // This wasn't the last ref our process had on
8438                            // the provider...  we have now been killed, bail.
8439                            return null;
8440                        }
8441                        providerRunning = false;
8442                        conn = null;
8443                    }
8444                }
8445
8446                Binder.restoreCallingIdentity(origId);
8447            }
8448
8449            boolean singleton;
8450            if (!providerRunning) {
8451                try {
8452                    cpi = AppGlobals.getPackageManager().
8453                        resolveContentProvider(name,
8454                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
8455                } catch (RemoteException ex) {
8456                }
8457                if (cpi == null) {
8458                    return null;
8459                }
8460                // If the provider is a singleton AND
8461                // (it's a call within the same user || the provider is a
8462                // privileged app)
8463                // Then allow connecting to the singleton provider
8464                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8465                        cpi.name, cpi.flags)
8466                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
8467                if (singleton) {
8468                    userId = UserHandle.USER_OWNER;
8469                }
8470                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
8471
8472                String msg;
8473                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
8474                        != null) {
8475                    throw new SecurityException(msg);
8476                }
8477
8478                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
8479                        && !cpi.processName.equals("system")) {
8480                    // If this content provider does not run in the system
8481                    // process, and the system is not yet ready to run other
8482                    // processes, then fail fast instead of hanging.
8483                    throw new IllegalArgumentException(
8484                            "Attempt to launch content provider before system ready");
8485                }
8486
8487                // Make sure that the user who owns this provider is started.  If not,
8488                // we don't want to allow it to run.
8489                if (mStartedUsers.get(userId) == null) {
8490                    Slog.w(TAG, "Unable to launch app "
8491                            + cpi.applicationInfo.packageName + "/"
8492                            + cpi.applicationInfo.uid + " for provider "
8493                            + name + ": user " + userId + " is stopped");
8494                    return null;
8495                }
8496
8497                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8498                cpr = mProviderMap.getProviderByClass(comp, userId);
8499                final boolean firstClass = cpr == null;
8500                if (firstClass) {
8501                    try {
8502                        ApplicationInfo ai =
8503                            AppGlobals.getPackageManager().
8504                                getApplicationInfo(
8505                                        cpi.applicationInfo.packageName,
8506                                        STOCK_PM_FLAGS, userId);
8507                        if (ai == null) {
8508                            Slog.w(TAG, "No package info for content provider "
8509                                    + cpi.name);
8510                            return null;
8511                        }
8512                        ai = getAppInfoForUser(ai, userId);
8513                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
8514                    } catch (RemoteException ex) {
8515                        // pm is in same process, this will never happen.
8516                    }
8517                }
8518
8519                if (r != null && cpr.canRunHere(r)) {
8520                    // If this is a multiprocess provider, then just return its
8521                    // info and allow the caller to instantiate it.  Only do
8522                    // this if the provider is the same user as the caller's
8523                    // process, or can run as root (so can be in any process).
8524                    return cpr.newHolder(null);
8525                }
8526
8527                if (DEBUG_PROVIDER) {
8528                    RuntimeException e = new RuntimeException("here");
8529                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
8530                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
8531                }
8532
8533                // This is single process, and our app is now connecting to it.
8534                // See if we are already in the process of launching this
8535                // provider.
8536                final int N = mLaunchingProviders.size();
8537                int i;
8538                for (i=0; i<N; i++) {
8539                    if (mLaunchingProviders.get(i) == cpr) {
8540                        break;
8541                    }
8542                }
8543
8544                // If the provider is not already being launched, then get it
8545                // started.
8546                if (i >= N) {
8547                    final long origId = Binder.clearCallingIdentity();
8548
8549                    try {
8550                        // Content provider is now in use, its package can't be stopped.
8551                        try {
8552                            AppGlobals.getPackageManager().setPackageStoppedState(
8553                                    cpr.appInfo.packageName, false, userId);
8554                        } catch (RemoteException e) {
8555                        } catch (IllegalArgumentException e) {
8556                            Slog.w(TAG, "Failed trying to unstop package "
8557                                    + cpr.appInfo.packageName + ": " + e);
8558                        }
8559
8560                        // Use existing process if already started
8561                        ProcessRecord proc = getProcessRecordLocked(
8562                                cpi.processName, cpr.appInfo.uid, false);
8563                        if (proc != null && proc.thread != null) {
8564                            if (DEBUG_PROVIDER) {
8565                                Slog.d(TAG, "Installing in existing process " + proc);
8566                            }
8567                            proc.pubProviders.put(cpi.name, cpr);
8568                            try {
8569                                proc.thread.scheduleInstallProvider(cpi);
8570                            } catch (RemoteException e) {
8571                            }
8572                        } else {
8573                            proc = startProcessLocked(cpi.processName,
8574                                    cpr.appInfo, false, 0, "content provider",
8575                                    new ComponentName(cpi.applicationInfo.packageName,
8576                                            cpi.name), false, false, false);
8577                            if (proc == null) {
8578                                Slog.w(TAG, "Unable to launch app "
8579                                        + cpi.applicationInfo.packageName + "/"
8580                                        + cpi.applicationInfo.uid + " for provider "
8581                                        + name + ": process is bad");
8582                                return null;
8583                            }
8584                        }
8585                        cpr.launchingApp = proc;
8586                        mLaunchingProviders.add(cpr);
8587                    } finally {
8588                        Binder.restoreCallingIdentity(origId);
8589                    }
8590                }
8591
8592                // Make sure the provider is published (the same provider class
8593                // may be published under multiple names).
8594                if (firstClass) {
8595                    mProviderMap.putProviderByClass(comp, cpr);
8596                }
8597
8598                mProviderMap.putProviderByName(name, cpr);
8599                conn = incProviderCountLocked(r, cpr, token, stable);
8600                if (conn != null) {
8601                    conn.waiting = true;
8602                }
8603            }
8604        }
8605
8606        // Wait for the provider to be published...
8607        synchronized (cpr) {
8608            while (cpr.provider == null) {
8609                if (cpr.launchingApp == null) {
8610                    Slog.w(TAG, "Unable to launch app "
8611                            + cpi.applicationInfo.packageName + "/"
8612                            + cpi.applicationInfo.uid + " for provider "
8613                            + name + ": launching app became null");
8614                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
8615                            UserHandle.getUserId(cpi.applicationInfo.uid),
8616                            cpi.applicationInfo.packageName,
8617                            cpi.applicationInfo.uid, name);
8618                    return null;
8619                }
8620                try {
8621                    if (DEBUG_MU) {
8622                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
8623                                + cpr.launchingApp);
8624                    }
8625                    if (conn != null) {
8626                        conn.waiting = true;
8627                    }
8628                    cpr.wait();
8629                } catch (InterruptedException ex) {
8630                } finally {
8631                    if (conn != null) {
8632                        conn.waiting = false;
8633                    }
8634                }
8635            }
8636        }
8637        return cpr != null ? cpr.newHolder(conn) : null;
8638    }
8639
8640    @Override
8641    public final ContentProviderHolder getContentProvider(
8642            IApplicationThread caller, String name, int userId, boolean stable) {
8643        enforceNotIsolatedCaller("getContentProvider");
8644        if (caller == null) {
8645            String msg = "null IApplicationThread when getting content provider "
8646                    + name;
8647            Slog.w(TAG, msg);
8648            throw new SecurityException(msg);
8649        }
8650        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
8651        // with cross-user grant.
8652        return getContentProviderImpl(caller, name, null, stable, userId);
8653    }
8654
8655    public ContentProviderHolder getContentProviderExternal(
8656            String name, int userId, IBinder token) {
8657        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8658            "Do not have permission in call getContentProviderExternal()");
8659        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
8660                false, ALLOW_FULL_ONLY, "getContentProvider", null);
8661        return getContentProviderExternalUnchecked(name, token, userId);
8662    }
8663
8664    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
8665            IBinder token, int userId) {
8666        return getContentProviderImpl(null, name, token, true, userId);
8667    }
8668
8669    /**
8670     * Drop a content provider from a ProcessRecord's bookkeeping
8671     */
8672    public void removeContentProvider(IBinder connection, boolean stable) {
8673        enforceNotIsolatedCaller("removeContentProvider");
8674        long ident = Binder.clearCallingIdentity();
8675        try {
8676            synchronized (this) {
8677                ContentProviderConnection conn;
8678                try {
8679                    conn = (ContentProviderConnection)connection;
8680                } catch (ClassCastException e) {
8681                    String msg ="removeContentProvider: " + connection
8682                            + " not a ContentProviderConnection";
8683                    Slog.w(TAG, msg);
8684                    throw new IllegalArgumentException(msg);
8685                }
8686                if (conn == null) {
8687                    throw new NullPointerException("connection is null");
8688                }
8689                if (decProviderCountLocked(conn, null, null, stable)) {
8690                    updateOomAdjLocked();
8691                }
8692            }
8693        } finally {
8694            Binder.restoreCallingIdentity(ident);
8695        }
8696    }
8697
8698    public void removeContentProviderExternal(String name, IBinder token) {
8699        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
8700            "Do not have permission in call removeContentProviderExternal()");
8701        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
8702    }
8703
8704    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
8705        synchronized (this) {
8706            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
8707            if(cpr == null) {
8708                //remove from mProvidersByClass
8709                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
8710                return;
8711            }
8712
8713            //update content provider record entry info
8714            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
8715            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
8716            if (localCpr.hasExternalProcessHandles()) {
8717                if (localCpr.removeExternalProcessHandleLocked(token)) {
8718                    updateOomAdjLocked();
8719                } else {
8720                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
8721                            + " with no external reference for token: "
8722                            + token + ".");
8723                }
8724            } else {
8725                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
8726                        + " with no external references.");
8727            }
8728        }
8729    }
8730
8731    public final void publishContentProviders(IApplicationThread caller,
8732            List<ContentProviderHolder> providers) {
8733        if (providers == null) {
8734            return;
8735        }
8736
8737        enforceNotIsolatedCaller("publishContentProviders");
8738        synchronized (this) {
8739            final ProcessRecord r = getRecordForAppLocked(caller);
8740            if (DEBUG_MU)
8741                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
8742            if (r == null) {
8743                throw new SecurityException(
8744                        "Unable to find app for caller " + caller
8745                      + " (pid=" + Binder.getCallingPid()
8746                      + ") when publishing content providers");
8747            }
8748
8749            final long origId = Binder.clearCallingIdentity();
8750
8751            final int N = providers.size();
8752            for (int i=0; i<N; i++) {
8753                ContentProviderHolder src = providers.get(i);
8754                if (src == null || src.info == null || src.provider == null) {
8755                    continue;
8756                }
8757                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
8758                if (DEBUG_MU)
8759                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
8760                if (dst != null) {
8761                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
8762                    mProviderMap.putProviderByClass(comp, dst);
8763                    String names[] = dst.info.authority.split(";");
8764                    for (int j = 0; j < names.length; j++) {
8765                        mProviderMap.putProviderByName(names[j], dst);
8766                    }
8767
8768                    int NL = mLaunchingProviders.size();
8769                    int j;
8770                    for (j=0; j<NL; j++) {
8771                        if (mLaunchingProviders.get(j) == dst) {
8772                            mLaunchingProviders.remove(j);
8773                            j--;
8774                            NL--;
8775                        }
8776                    }
8777                    synchronized (dst) {
8778                        dst.provider = src.provider;
8779                        dst.proc = r;
8780                        dst.notifyAll();
8781                    }
8782                    updateOomAdjLocked(r);
8783                }
8784            }
8785
8786            Binder.restoreCallingIdentity(origId);
8787        }
8788    }
8789
8790    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
8791        ContentProviderConnection conn;
8792        try {
8793            conn = (ContentProviderConnection)connection;
8794        } catch (ClassCastException e) {
8795            String msg ="refContentProvider: " + connection
8796                    + " not a ContentProviderConnection";
8797            Slog.w(TAG, msg);
8798            throw new IllegalArgumentException(msg);
8799        }
8800        if (conn == null) {
8801            throw new NullPointerException("connection is null");
8802        }
8803
8804        synchronized (this) {
8805            if (stable > 0) {
8806                conn.numStableIncs += stable;
8807            }
8808            stable = conn.stableCount + stable;
8809            if (stable < 0) {
8810                throw new IllegalStateException("stableCount < 0: " + stable);
8811            }
8812
8813            if (unstable > 0) {
8814                conn.numUnstableIncs += unstable;
8815            }
8816            unstable = conn.unstableCount + unstable;
8817            if (unstable < 0) {
8818                throw new IllegalStateException("unstableCount < 0: " + unstable);
8819            }
8820
8821            if ((stable+unstable) <= 0) {
8822                throw new IllegalStateException("ref counts can't go to zero here: stable="
8823                        + stable + " unstable=" + unstable);
8824            }
8825            conn.stableCount = stable;
8826            conn.unstableCount = unstable;
8827            return !conn.dead;
8828        }
8829    }
8830
8831    public void unstableProviderDied(IBinder connection) {
8832        ContentProviderConnection conn;
8833        try {
8834            conn = (ContentProviderConnection)connection;
8835        } catch (ClassCastException e) {
8836            String msg ="refContentProvider: " + connection
8837                    + " not a ContentProviderConnection";
8838            Slog.w(TAG, msg);
8839            throw new IllegalArgumentException(msg);
8840        }
8841        if (conn == null) {
8842            throw new NullPointerException("connection is null");
8843        }
8844
8845        // Safely retrieve the content provider associated with the connection.
8846        IContentProvider provider;
8847        synchronized (this) {
8848            provider = conn.provider.provider;
8849        }
8850
8851        if (provider == null) {
8852            // Um, yeah, we're way ahead of you.
8853            return;
8854        }
8855
8856        // Make sure the caller is being honest with us.
8857        if (provider.asBinder().pingBinder()) {
8858            // Er, no, still looks good to us.
8859            synchronized (this) {
8860                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
8861                        + " says " + conn + " died, but we don't agree");
8862                return;
8863            }
8864        }
8865
8866        // Well look at that!  It's dead!
8867        synchronized (this) {
8868            if (conn.provider.provider != provider) {
8869                // But something changed...  good enough.
8870                return;
8871            }
8872
8873            ProcessRecord proc = conn.provider.proc;
8874            if (proc == null || proc.thread == null) {
8875                // Seems like the process is already cleaned up.
8876                return;
8877            }
8878
8879            // As far as we're concerned, this is just like receiving a
8880            // death notification...  just a bit prematurely.
8881            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
8882                    + ") early provider death");
8883            final long ident = Binder.clearCallingIdentity();
8884            try {
8885                appDiedLocked(proc, proc.pid, proc.thread);
8886            } finally {
8887                Binder.restoreCallingIdentity(ident);
8888            }
8889        }
8890    }
8891
8892    @Override
8893    public void appNotRespondingViaProvider(IBinder connection) {
8894        enforceCallingPermission(
8895                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
8896
8897        final ContentProviderConnection conn = (ContentProviderConnection) connection;
8898        if (conn == null) {
8899            Slog.w(TAG, "ContentProviderConnection is null");
8900            return;
8901        }
8902
8903        final ProcessRecord host = conn.provider.proc;
8904        if (host == null) {
8905            Slog.w(TAG, "Failed to find hosting ProcessRecord");
8906            return;
8907        }
8908
8909        final long token = Binder.clearCallingIdentity();
8910        try {
8911            appNotResponding(host, null, null, false, "ContentProvider not responding");
8912        } finally {
8913            Binder.restoreCallingIdentity(token);
8914        }
8915    }
8916
8917    public final void installSystemProviders() {
8918        List<ProviderInfo> providers;
8919        synchronized (this) {
8920            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
8921            providers = generateApplicationProvidersLocked(app);
8922            if (providers != null) {
8923                for (int i=providers.size()-1; i>=0; i--) {
8924                    ProviderInfo pi = (ProviderInfo)providers.get(i);
8925                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
8926                        Slog.w(TAG, "Not installing system proc provider " + pi.name
8927                                + ": not system .apk");
8928                        providers.remove(i);
8929                    }
8930                }
8931            }
8932        }
8933        if (providers != null) {
8934            mSystemThread.installSystemProviders(providers);
8935        }
8936
8937        mCoreSettingsObserver = new CoreSettingsObserver(this);
8938
8939        //mUsageStatsService.monitorPackages();
8940    }
8941
8942    /**
8943     * Allows app to retrieve the MIME type of a URI without having permission
8944     * to access its content provider.
8945     *
8946     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
8947     *
8948     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
8949     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
8950     */
8951    public String getProviderMimeType(Uri uri, int userId) {
8952        enforceNotIsolatedCaller("getProviderMimeType");
8953        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
8954                userId, false, ALLOW_NON_FULL_IN_PROFILE, "getProviderMimeType", null);
8955        final String name = uri.getAuthority();
8956        final long ident = Binder.clearCallingIdentity();
8957        ContentProviderHolder holder = null;
8958
8959        try {
8960            holder = getContentProviderExternalUnchecked(name, null, userId);
8961            if (holder != null) {
8962                return holder.provider.getType(uri);
8963            }
8964        } catch (RemoteException e) {
8965            Log.w(TAG, "Content provider dead retrieving " + uri, e);
8966            return null;
8967        } finally {
8968            if (holder != null) {
8969                removeContentProviderExternalUnchecked(name, null, userId);
8970            }
8971            Binder.restoreCallingIdentity(ident);
8972        }
8973
8974        return null;
8975    }
8976
8977    // =========================================================
8978    // GLOBAL MANAGEMENT
8979    // =========================================================
8980
8981    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
8982            boolean isolated, int isolatedUid) {
8983        String proc = customProcess != null ? customProcess : info.processName;
8984        BatteryStatsImpl.Uid.Proc ps = null;
8985        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
8986        int uid = info.uid;
8987        if (isolated) {
8988            if (isolatedUid == 0) {
8989                int userId = UserHandle.getUserId(uid);
8990                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
8991                while (true) {
8992                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
8993                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
8994                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
8995                    }
8996                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
8997                    mNextIsolatedProcessUid++;
8998                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
8999                        // No process for this uid, use it.
9000                        break;
9001                    }
9002                    stepsLeft--;
9003                    if (stepsLeft <= 0) {
9004                        return null;
9005                    }
9006                }
9007            } else {
9008                // Special case for startIsolatedProcess (internal only), where
9009                // the uid of the isolated process is specified by the caller.
9010                uid = isolatedUid;
9011            }
9012        }
9013        return new ProcessRecord(stats, info, proc, uid);
9014    }
9015
9016    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9017            String abiOverride) {
9018        ProcessRecord app;
9019        if (!isolated) {
9020            app = getProcessRecordLocked(info.processName, info.uid, true);
9021        } else {
9022            app = null;
9023        }
9024
9025        if (app == null) {
9026            app = newProcessRecordLocked(info, null, isolated, 0);
9027            mProcessNames.put(info.processName, app.uid, app);
9028            if (isolated) {
9029                mIsolatedProcesses.put(app.uid, app);
9030            }
9031            updateLruProcessLocked(app, false, null);
9032            updateOomAdjLocked();
9033        }
9034
9035        // This package really, really can not be stopped.
9036        try {
9037            AppGlobals.getPackageManager().setPackageStoppedState(
9038                    info.packageName, false, UserHandle.getUserId(app.uid));
9039        } catch (RemoteException e) {
9040        } catch (IllegalArgumentException e) {
9041            Slog.w(TAG, "Failed trying to unstop package "
9042                    + info.packageName + ": " + e);
9043        }
9044
9045        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9046                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9047            app.persistent = true;
9048            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9049        }
9050        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9051            mPersistentStartingProcesses.add(app);
9052            startProcessLocked(app, "added application", app.processName, abiOverride,
9053                    null /* entryPoint */, null /* entryPointArgs */);
9054        }
9055
9056        return app;
9057    }
9058
9059    public void unhandledBack() {
9060        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9061                "unhandledBack()");
9062
9063        synchronized(this) {
9064            final long origId = Binder.clearCallingIdentity();
9065            try {
9066                getFocusedStack().unhandledBackLocked();
9067            } finally {
9068                Binder.restoreCallingIdentity(origId);
9069            }
9070        }
9071    }
9072
9073    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9074        enforceNotIsolatedCaller("openContentUri");
9075        final int userId = UserHandle.getCallingUserId();
9076        String name = uri.getAuthority();
9077        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9078        ParcelFileDescriptor pfd = null;
9079        if (cph != null) {
9080            // We record the binder invoker's uid in thread-local storage before
9081            // going to the content provider to open the file.  Later, in the code
9082            // that handles all permissions checks, we look for this uid and use
9083            // that rather than the Activity Manager's own uid.  The effect is that
9084            // we do the check against the caller's permissions even though it looks
9085            // to the content provider like the Activity Manager itself is making
9086            // the request.
9087            sCallerIdentity.set(new Identity(
9088                    Binder.getCallingPid(), Binder.getCallingUid()));
9089            try {
9090                pfd = cph.provider.openFile(null, uri, "r", null);
9091            } catch (FileNotFoundException e) {
9092                // do nothing; pfd will be returned null
9093            } finally {
9094                // Ensure that whatever happens, we clean up the identity state
9095                sCallerIdentity.remove();
9096            }
9097
9098            // We've got the fd now, so we're done with the provider.
9099            removeContentProviderExternalUnchecked(name, null, userId);
9100        } else {
9101            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9102        }
9103        return pfd;
9104    }
9105
9106    // Actually is sleeping or shutting down or whatever else in the future
9107    // is an inactive state.
9108    public boolean isSleepingOrShuttingDown() {
9109        return mSleeping || mShuttingDown;
9110    }
9111
9112    public boolean isSleeping() {
9113        return mSleeping;
9114    }
9115
9116    void goingToSleep() {
9117        synchronized(this) {
9118            mWentToSleep = true;
9119            updateEventDispatchingLocked();
9120            goToSleepIfNeededLocked();
9121        }
9122    }
9123
9124    void finishRunningVoiceLocked() {
9125        if (mRunningVoice) {
9126            mRunningVoice = false;
9127            goToSleepIfNeededLocked();
9128        }
9129    }
9130
9131    void goToSleepIfNeededLocked() {
9132        if (mWentToSleep && !mRunningVoice) {
9133            if (!mSleeping) {
9134                mSleeping = true;
9135                mStackSupervisor.goingToSleepLocked();
9136
9137                // Initialize the wake times of all processes.
9138                checkExcessivePowerUsageLocked(false);
9139                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9140                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9141                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9142            }
9143        }
9144    }
9145
9146    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9147        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9148            // Never persist the home stack.
9149            return;
9150        }
9151        mTaskPersister.wakeup(task, flush);
9152    }
9153
9154    @Override
9155    public boolean shutdown(int timeout) {
9156        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9157                != PackageManager.PERMISSION_GRANTED) {
9158            throw new SecurityException("Requires permission "
9159                    + android.Manifest.permission.SHUTDOWN);
9160        }
9161
9162        boolean timedout = false;
9163
9164        synchronized(this) {
9165            mShuttingDown = true;
9166            updateEventDispatchingLocked();
9167            timedout = mStackSupervisor.shutdownLocked(timeout);
9168        }
9169
9170        mAppOpsService.shutdown();
9171        if (mUsageStatsService != null) {
9172            mUsageStatsService.prepareShutdown();
9173        }
9174        mBatteryStatsService.shutdown();
9175        synchronized (this) {
9176            mProcessStats.shutdownLocked();
9177        }
9178        notifyTaskPersisterLocked(null, true);
9179
9180        return timedout;
9181    }
9182
9183    public final void activitySlept(IBinder token) {
9184        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9185
9186        final long origId = Binder.clearCallingIdentity();
9187
9188        synchronized (this) {
9189            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9190            if (r != null) {
9191                mStackSupervisor.activitySleptLocked(r);
9192            }
9193        }
9194
9195        Binder.restoreCallingIdentity(origId);
9196    }
9197
9198    void logLockScreen(String msg) {
9199        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9200                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9201                mWentToSleep + " mSleeping=" + mSleeping + " mDismissKeyguardOnNextActivity=" +
9202                mStackSupervisor.mDismissKeyguardOnNextActivity);
9203    }
9204
9205    private void comeOutOfSleepIfNeededLocked() {
9206        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9207            if (mSleeping) {
9208                mSleeping = false;
9209                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9210            }
9211        }
9212    }
9213
9214    void wakingUp() {
9215        synchronized(this) {
9216            mWentToSleep = false;
9217            updateEventDispatchingLocked();
9218            comeOutOfSleepIfNeededLocked();
9219        }
9220    }
9221
9222    void startRunningVoiceLocked() {
9223        if (!mRunningVoice) {
9224            mRunningVoice = true;
9225            comeOutOfSleepIfNeededLocked();
9226        }
9227    }
9228
9229    private void updateEventDispatchingLocked() {
9230        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9231    }
9232
9233    public void setLockScreenShown(boolean shown) {
9234        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9235                != PackageManager.PERMISSION_GRANTED) {
9236            throw new SecurityException("Requires permission "
9237                    + android.Manifest.permission.DEVICE_POWER);
9238        }
9239
9240        synchronized(this) {
9241            long ident = Binder.clearCallingIdentity();
9242            try {
9243                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9244                mLockScreenShown = shown;
9245                comeOutOfSleepIfNeededLocked();
9246            } finally {
9247                Binder.restoreCallingIdentity(ident);
9248            }
9249        }
9250    }
9251
9252    @Override
9253    public void stopAppSwitches() {
9254        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9255                != PackageManager.PERMISSION_GRANTED) {
9256            throw new SecurityException("Requires permission "
9257                    + android.Manifest.permission.STOP_APP_SWITCHES);
9258        }
9259
9260        synchronized(this) {
9261            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9262                    + APP_SWITCH_DELAY_TIME;
9263            mDidAppSwitch = false;
9264            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9265            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9266            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9267        }
9268    }
9269
9270    public void resumeAppSwitches() {
9271        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9272                != PackageManager.PERMISSION_GRANTED) {
9273            throw new SecurityException("Requires permission "
9274                    + android.Manifest.permission.STOP_APP_SWITCHES);
9275        }
9276
9277        synchronized(this) {
9278            // Note that we don't execute any pending app switches... we will
9279            // let those wait until either the timeout, or the next start
9280            // activity request.
9281            mAppSwitchesAllowedTime = 0;
9282        }
9283    }
9284
9285    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9286            String name) {
9287        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9288            return true;
9289        }
9290
9291        final int perm = checkComponentPermission(
9292                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9293                callingUid, -1, true);
9294        if (perm == PackageManager.PERMISSION_GRANTED) {
9295            return true;
9296        }
9297
9298        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9299        return false;
9300    }
9301
9302    public void setDebugApp(String packageName, boolean waitForDebugger,
9303            boolean persistent) {
9304        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9305                "setDebugApp()");
9306
9307        long ident = Binder.clearCallingIdentity();
9308        try {
9309            // Note that this is not really thread safe if there are multiple
9310            // callers into it at the same time, but that's not a situation we
9311            // care about.
9312            if (persistent) {
9313                final ContentResolver resolver = mContext.getContentResolver();
9314                Settings.Global.putString(
9315                    resolver, Settings.Global.DEBUG_APP,
9316                    packageName);
9317                Settings.Global.putInt(
9318                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9319                    waitForDebugger ? 1 : 0);
9320            }
9321
9322            synchronized (this) {
9323                if (!persistent) {
9324                    mOrigDebugApp = mDebugApp;
9325                    mOrigWaitForDebugger = mWaitForDebugger;
9326                }
9327                mDebugApp = packageName;
9328                mWaitForDebugger = waitForDebugger;
9329                mDebugTransient = !persistent;
9330                if (packageName != null) {
9331                    forceStopPackageLocked(packageName, -1, false, false, true, true,
9332                            false, UserHandle.USER_ALL, "set debug app");
9333                }
9334            }
9335        } finally {
9336            Binder.restoreCallingIdentity(ident);
9337        }
9338    }
9339
9340    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
9341        synchronized (this) {
9342            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9343            if (!isDebuggable) {
9344                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9345                    throw new SecurityException("Process not debuggable: " + app.packageName);
9346                }
9347            }
9348
9349            mOpenGlTraceApp = processName;
9350        }
9351    }
9352
9353    void setProfileApp(ApplicationInfo app, String processName, String profileFile,
9354            ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
9355        synchronized (this) {
9356            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
9357            if (!isDebuggable) {
9358                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
9359                    throw new SecurityException("Process not debuggable: " + app.packageName);
9360                }
9361            }
9362            mProfileApp = processName;
9363            mProfileFile = profileFile;
9364            if (mProfileFd != null) {
9365                try {
9366                    mProfileFd.close();
9367                } catch (IOException e) {
9368                }
9369                mProfileFd = null;
9370            }
9371            mProfileFd = profileFd;
9372            mProfileType = 0;
9373            mAutoStopProfiler = autoStopProfiler;
9374        }
9375    }
9376
9377    @Override
9378    public void setAlwaysFinish(boolean enabled) {
9379        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
9380                "setAlwaysFinish()");
9381
9382        Settings.Global.putInt(
9383                mContext.getContentResolver(),
9384                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
9385
9386        synchronized (this) {
9387            mAlwaysFinishActivities = enabled;
9388        }
9389    }
9390
9391    @Override
9392    public void setActivityController(IActivityController controller) {
9393        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9394                "setActivityController()");
9395        synchronized (this) {
9396            mController = controller;
9397            Watchdog.getInstance().setActivityController(controller);
9398        }
9399    }
9400
9401    @Override
9402    public void setUserIsMonkey(boolean userIsMonkey) {
9403        synchronized (this) {
9404            synchronized (mPidsSelfLocked) {
9405                final int callingPid = Binder.getCallingPid();
9406                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
9407                if (precessRecord == null) {
9408                    throw new SecurityException("Unknown process: " + callingPid);
9409                }
9410                if (precessRecord.instrumentationUiAutomationConnection  == null) {
9411                    throw new SecurityException("Only an instrumentation process "
9412                            + "with a UiAutomation can call setUserIsMonkey");
9413                }
9414            }
9415            mUserIsMonkey = userIsMonkey;
9416        }
9417    }
9418
9419    @Override
9420    public boolean isUserAMonkey() {
9421        synchronized (this) {
9422            // If there is a controller also implies the user is a monkey.
9423            return (mUserIsMonkey || mController != null);
9424        }
9425    }
9426
9427    public void requestBugReport() {
9428        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
9429        SystemProperties.set("ctl.start", "bugreport");
9430    }
9431
9432    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
9433        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
9434    }
9435
9436    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
9437        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
9438            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
9439        }
9440        return KEY_DISPATCHING_TIMEOUT;
9441    }
9442
9443    @Override
9444    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
9445        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9446                != PackageManager.PERMISSION_GRANTED) {
9447            throw new SecurityException("Requires permission "
9448                    + android.Manifest.permission.FILTER_EVENTS);
9449        }
9450        ProcessRecord proc;
9451        long timeout;
9452        synchronized (this) {
9453            synchronized (mPidsSelfLocked) {
9454                proc = mPidsSelfLocked.get(pid);
9455            }
9456            timeout = getInputDispatchingTimeoutLocked(proc);
9457        }
9458
9459        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
9460            return -1;
9461        }
9462
9463        return timeout;
9464    }
9465
9466    /**
9467     * Handle input dispatching timeouts.
9468     * Returns whether input dispatching should be aborted or not.
9469     */
9470    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
9471            final ActivityRecord activity, final ActivityRecord parent,
9472            final boolean aboveSystem, String reason) {
9473        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
9474                != PackageManager.PERMISSION_GRANTED) {
9475            throw new SecurityException("Requires permission "
9476                    + android.Manifest.permission.FILTER_EVENTS);
9477        }
9478
9479        final String annotation;
9480        if (reason == null) {
9481            annotation = "Input dispatching timed out";
9482        } else {
9483            annotation = "Input dispatching timed out (" + reason + ")";
9484        }
9485
9486        if (proc != null) {
9487            synchronized (this) {
9488                if (proc.debugging) {
9489                    return false;
9490                }
9491
9492                if (mDidDexOpt) {
9493                    // Give more time since we were dexopting.
9494                    mDidDexOpt = false;
9495                    return false;
9496                }
9497
9498                if (proc.instrumentationClass != null) {
9499                    Bundle info = new Bundle();
9500                    info.putString("shortMsg", "keyDispatchingTimedOut");
9501                    info.putString("longMsg", annotation);
9502                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
9503                    return true;
9504                }
9505            }
9506            mHandler.post(new Runnable() {
9507                @Override
9508                public void run() {
9509                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
9510                }
9511            });
9512        }
9513
9514        return true;
9515    }
9516
9517    public Bundle getAssistContextExtras(int requestType) {
9518        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
9519                "getAssistContextExtras()");
9520        PendingAssistExtras pae;
9521        Bundle extras = new Bundle();
9522        synchronized (this) {
9523            ActivityRecord activity = getFocusedStack().mResumedActivity;
9524            if (activity == null) {
9525                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
9526                return null;
9527            }
9528            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
9529            if (activity.app == null || activity.app.thread == null) {
9530                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
9531                return extras;
9532            }
9533            if (activity.app.pid == Binder.getCallingPid()) {
9534                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
9535                return extras;
9536            }
9537            pae = new PendingAssistExtras(activity);
9538            try {
9539                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
9540                        requestType);
9541                mPendingAssistExtras.add(pae);
9542                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
9543            } catch (RemoteException e) {
9544                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
9545                return extras;
9546            }
9547        }
9548        synchronized (pae) {
9549            while (!pae.haveResult) {
9550                try {
9551                    pae.wait();
9552                } catch (InterruptedException e) {
9553                }
9554            }
9555            if (pae.result != null) {
9556                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
9557            }
9558        }
9559        synchronized (this) {
9560            mPendingAssistExtras.remove(pae);
9561            mHandler.removeCallbacks(pae);
9562        }
9563        return extras;
9564    }
9565
9566    public void reportAssistContextExtras(IBinder token, Bundle extras) {
9567        PendingAssistExtras pae = (PendingAssistExtras)token;
9568        synchronized (pae) {
9569            pae.result = extras;
9570            pae.haveResult = true;
9571            pae.notifyAll();
9572        }
9573    }
9574
9575    public void registerProcessObserver(IProcessObserver observer) {
9576        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
9577                "registerProcessObserver()");
9578        synchronized (this) {
9579            mProcessObservers.register(observer);
9580        }
9581    }
9582
9583    @Override
9584    public void unregisterProcessObserver(IProcessObserver observer) {
9585        synchronized (this) {
9586            mProcessObservers.unregister(observer);
9587        }
9588    }
9589
9590    @Override
9591    public boolean convertFromTranslucent(IBinder token) {
9592        final long origId = Binder.clearCallingIdentity();
9593        try {
9594            synchronized (this) {
9595                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9596                if (r == null) {
9597                    return false;
9598                }
9599                if (r.changeWindowTranslucency(true)) {
9600                    mWindowManager.setAppFullscreen(token, true);
9601                    r.task.stack.releaseMediaResources();
9602                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9603                    return true;
9604                }
9605                return false;
9606            }
9607        } finally {
9608            Binder.restoreCallingIdentity(origId);
9609        }
9610    }
9611
9612    @Override
9613    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
9614        final long origId = Binder.clearCallingIdentity();
9615        try {
9616            synchronized (this) {
9617                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9618                if (r == null) {
9619                    return false;
9620                }
9621                int index = r.task.mActivities.lastIndexOf(r);
9622                if (index > 0) {
9623                    ActivityRecord under = r.task.mActivities.get(index - 1);
9624                    under.returningOptions = options;
9625                }
9626                if (r.changeWindowTranslucency(false)) {
9627                    r.task.stack.convertToTranslucent(r);
9628                    mWindowManager.setAppFullscreen(token, false);
9629                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9630                    return true;
9631                } else {
9632                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
9633                    return false;
9634                }
9635            }
9636        } finally {
9637            Binder.restoreCallingIdentity(origId);
9638        }
9639    }
9640
9641    @Override
9642    public boolean setMediaPlaying(IBinder token, boolean playing) {
9643        final long origId = Binder.clearCallingIdentity();
9644        try {
9645            synchronized (this) {
9646                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9647                if (r != null) {
9648                    return mStackSupervisor.setMediaPlayingLocked(r, playing);
9649                }
9650            }
9651            return false;
9652        } finally {
9653            Binder.restoreCallingIdentity(origId);
9654        }
9655    }
9656
9657    @Override
9658    public boolean isBackgroundMediaPlaying(IBinder token) {
9659        final long origId = Binder.clearCallingIdentity();
9660        try {
9661            synchronized (this) {
9662                final ActivityStack stack = ActivityRecord.getStackLocked(token);
9663                final boolean playing = stack == null ? false : stack.isMediaPlaying();
9664                if (ActivityStackSupervisor.DEBUG_MEDIA_VISIBILITY) Slog.d(TAG,
9665                        "isBackgroundMediaPlaying: stack=" + stack + " playing=" + playing);
9666                return playing;
9667            }
9668        } finally {
9669            Binder.restoreCallingIdentity(origId);
9670        }
9671    }
9672
9673    @Override
9674    public ActivityOptions getActivityOptions(IBinder token) {
9675        final long origId = Binder.clearCallingIdentity();
9676        try {
9677            synchronized (this) {
9678                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9679                if (r != null) {
9680                    final ActivityOptions activityOptions = r.pendingOptions;
9681                    r.pendingOptions = null;
9682                    return activityOptions;
9683                }
9684                return null;
9685            }
9686        } finally {
9687            Binder.restoreCallingIdentity(origId);
9688        }
9689    }
9690
9691    @Override
9692    public void setImmersive(IBinder token, boolean immersive) {
9693        synchronized(this) {
9694            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9695            if (r == null) {
9696                throw new IllegalArgumentException();
9697            }
9698            r.immersive = immersive;
9699
9700            // update associated state if we're frontmost
9701            if (r == mFocusedActivity) {
9702                if (DEBUG_IMMERSIVE) {
9703                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
9704                }
9705                applyUpdateLockStateLocked(r);
9706            }
9707        }
9708    }
9709
9710    @Override
9711    public boolean isImmersive(IBinder token) {
9712        synchronized (this) {
9713            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9714            if (r == null) {
9715                throw new IllegalArgumentException();
9716            }
9717            return r.immersive;
9718        }
9719    }
9720
9721    public boolean isTopActivityImmersive() {
9722        enforceNotIsolatedCaller("startActivity");
9723        synchronized (this) {
9724            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
9725            return (r != null) ? r.immersive : false;
9726        }
9727    }
9728
9729    @Override
9730    public boolean isTopOfTask(IBinder token) {
9731        synchronized (this) {
9732            ActivityRecord r = ActivityRecord.isInStackLocked(token);
9733            if (r == null) {
9734                throw new IllegalArgumentException();
9735            }
9736            return r.task.getTopActivity() == r;
9737        }
9738    }
9739
9740    public final void enterSafeMode() {
9741        synchronized(this) {
9742            // It only makes sense to do this before the system is ready
9743            // and started launching other packages.
9744            if (!mSystemReady) {
9745                try {
9746                    AppGlobals.getPackageManager().enterSafeMode();
9747                } catch (RemoteException e) {
9748                }
9749            }
9750
9751            mSafeMode = true;
9752        }
9753    }
9754
9755    public final void showSafeModeOverlay() {
9756        View v = LayoutInflater.from(mContext).inflate(
9757                com.android.internal.R.layout.safe_mode, null);
9758        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
9759        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
9760        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
9761        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
9762        lp.gravity = Gravity.BOTTOM | Gravity.START;
9763        lp.format = v.getBackground().getOpacity();
9764        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
9765                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
9766        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
9767        ((WindowManager)mContext.getSystemService(
9768                Context.WINDOW_SERVICE)).addView(v, lp);
9769    }
9770
9771    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
9772        if (!(sender instanceof PendingIntentRecord)) {
9773            return;
9774        }
9775        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9776        synchronized (stats) {
9777            if (mBatteryStatsService.isOnBattery()) {
9778                mBatteryStatsService.enforceCallingPermission();
9779                PendingIntentRecord rec = (PendingIntentRecord)sender;
9780                int MY_UID = Binder.getCallingUid();
9781                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
9782                BatteryStatsImpl.Uid.Pkg pkg =
9783                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
9784                            sourcePkg != null ? sourcePkg : rec.key.packageName);
9785                pkg.incWakeupsLocked();
9786            }
9787        }
9788    }
9789
9790    public boolean killPids(int[] pids, String pReason, boolean secure) {
9791        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9792            throw new SecurityException("killPids only available to the system");
9793        }
9794        String reason = (pReason == null) ? "Unknown" : pReason;
9795        // XXX Note: don't acquire main activity lock here, because the window
9796        // manager calls in with its locks held.
9797
9798        boolean killed = false;
9799        synchronized (mPidsSelfLocked) {
9800            int[] types = new int[pids.length];
9801            int worstType = 0;
9802            for (int i=0; i<pids.length; i++) {
9803                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9804                if (proc != null) {
9805                    int type = proc.setAdj;
9806                    types[i] = type;
9807                    if (type > worstType) {
9808                        worstType = type;
9809                    }
9810                }
9811            }
9812
9813            // If the worst oom_adj is somewhere in the cached proc LRU range,
9814            // then constrain it so we will kill all cached procs.
9815            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
9816                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
9817                worstType = ProcessList.CACHED_APP_MIN_ADJ;
9818            }
9819
9820            // If this is not a secure call, don't let it kill processes that
9821            // are important.
9822            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
9823                worstType = ProcessList.SERVICE_ADJ;
9824            }
9825
9826            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
9827            for (int i=0; i<pids.length; i++) {
9828                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
9829                if (proc == null) {
9830                    continue;
9831                }
9832                int adj = proc.setAdj;
9833                if (adj >= worstType && !proc.killedByAm) {
9834                    killUnneededProcessLocked(proc, reason);
9835                    killed = true;
9836                }
9837            }
9838        }
9839        return killed;
9840    }
9841
9842    @Override
9843    public void killUid(int uid, String reason) {
9844        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9845            throw new SecurityException("killUid only available to the system");
9846        }
9847        synchronized (this) {
9848            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
9849                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
9850                    reason != null ? reason : "kill uid");
9851        }
9852    }
9853
9854    @Override
9855    public boolean killProcessesBelowForeground(String reason) {
9856        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9857            throw new SecurityException("killProcessesBelowForeground() only available to system");
9858        }
9859
9860        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
9861    }
9862
9863    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
9864        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
9865            throw new SecurityException("killProcessesBelowAdj() only available to system");
9866        }
9867
9868        boolean killed = false;
9869        synchronized (mPidsSelfLocked) {
9870            final int size = mPidsSelfLocked.size();
9871            for (int i = 0; i < size; i++) {
9872                final int pid = mPidsSelfLocked.keyAt(i);
9873                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
9874                if (proc == null) continue;
9875
9876                final int adj = proc.setAdj;
9877                if (adj > belowAdj && !proc.killedByAm) {
9878                    killUnneededProcessLocked(proc, reason);
9879                    killed = true;
9880                }
9881            }
9882        }
9883        return killed;
9884    }
9885
9886    @Override
9887    public void hang(final IBinder who, boolean allowRestart) {
9888        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9889                != PackageManager.PERMISSION_GRANTED) {
9890            throw new SecurityException("Requires permission "
9891                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9892        }
9893
9894        final IBinder.DeathRecipient death = new DeathRecipient() {
9895            @Override
9896            public void binderDied() {
9897                synchronized (this) {
9898                    notifyAll();
9899                }
9900            }
9901        };
9902
9903        try {
9904            who.linkToDeath(death, 0);
9905        } catch (RemoteException e) {
9906            Slog.w(TAG, "hang: given caller IBinder is already dead.");
9907            return;
9908        }
9909
9910        synchronized (this) {
9911            Watchdog.getInstance().setAllowRestart(allowRestart);
9912            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
9913            synchronized (death) {
9914                while (who.isBinderAlive()) {
9915                    try {
9916                        death.wait();
9917                    } catch (InterruptedException e) {
9918                    }
9919                }
9920            }
9921            Watchdog.getInstance().setAllowRestart(true);
9922        }
9923    }
9924
9925    @Override
9926    public void restart() {
9927        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9928                != PackageManager.PERMISSION_GRANTED) {
9929            throw new SecurityException("Requires permission "
9930                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9931        }
9932
9933        Log.i(TAG, "Sending shutdown broadcast...");
9934
9935        BroadcastReceiver br = new BroadcastReceiver() {
9936            @Override public void onReceive(Context context, Intent intent) {
9937                // Now the broadcast is done, finish up the low-level shutdown.
9938                Log.i(TAG, "Shutting down activity manager...");
9939                shutdown(10000);
9940                Log.i(TAG, "Shutdown complete, restarting!");
9941                Process.killProcess(Process.myPid());
9942                System.exit(10);
9943            }
9944        };
9945
9946        // First send the high-level shut down broadcast.
9947        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
9948        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
9949        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
9950        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
9951        mContext.sendOrderedBroadcastAsUser(intent,
9952                UserHandle.ALL, null, br, mHandler, 0, null, null);
9953        */
9954        br.onReceive(mContext, intent);
9955    }
9956
9957    private long getLowRamTimeSinceIdle(long now) {
9958        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
9959    }
9960
9961    @Override
9962    public void performIdleMaintenance() {
9963        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
9964                != PackageManager.PERMISSION_GRANTED) {
9965            throw new SecurityException("Requires permission "
9966                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
9967        }
9968
9969        synchronized (this) {
9970            final long now = SystemClock.uptimeMillis();
9971            final long timeSinceLastIdle = now - mLastIdleTime;
9972            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
9973            mLastIdleTime = now;
9974            mLowRamTimeSinceLastIdle = 0;
9975            if (mLowRamStartTime != 0) {
9976                mLowRamStartTime = now;
9977            }
9978
9979            StringBuilder sb = new StringBuilder(128);
9980            sb.append("Idle maintenance over ");
9981            TimeUtils.formatDuration(timeSinceLastIdle, sb);
9982            sb.append(" low RAM for ");
9983            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
9984            Slog.i(TAG, sb.toString());
9985
9986            // If at least 1/3 of our time since the last idle period has been spent
9987            // with RAM low, then we want to kill processes.
9988            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
9989
9990            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
9991                ProcessRecord proc = mLruProcesses.get(i);
9992                if (proc.notCachedSinceIdle) {
9993                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
9994                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
9995                        if (doKilling && proc.initialIdlePss != 0
9996                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
9997                            killUnneededProcessLocked(proc, "idle maint (pss " + proc.lastPss
9998                                    + " from " + proc.initialIdlePss + ")");
9999                        }
10000                    }
10001                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10002                    proc.notCachedSinceIdle = true;
10003                    proc.initialIdlePss = 0;
10004                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10005                            isSleeping(), now);
10006                }
10007            }
10008
10009            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10010            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10011        }
10012    }
10013
10014    private void retrieveSettings() {
10015        final ContentResolver resolver = mContext.getContentResolver();
10016        String debugApp = Settings.Global.getString(
10017            resolver, Settings.Global.DEBUG_APP);
10018        boolean waitForDebugger = Settings.Global.getInt(
10019            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10020        boolean alwaysFinishActivities = Settings.Global.getInt(
10021            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10022        boolean forceRtl = Settings.Global.getInt(
10023                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10024        // Transfer any global setting for forcing RTL layout, into a System Property
10025        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10026
10027        Configuration configuration = new Configuration();
10028        Settings.System.getConfiguration(resolver, configuration);
10029        if (forceRtl) {
10030            // This will take care of setting the correct layout direction flags
10031            configuration.setLayoutDirection(configuration.locale);
10032        }
10033
10034        synchronized (this) {
10035            mDebugApp = mOrigDebugApp = debugApp;
10036            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10037            mAlwaysFinishActivities = alwaysFinishActivities;
10038            // This happens before any activities are started, so we can
10039            // change mConfiguration in-place.
10040            updateConfigurationLocked(configuration, null, false, true);
10041            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10042        }
10043    }
10044
10045    public boolean testIsSystemReady() {
10046        // no need to synchronize(this) just to read & return the value
10047        return mSystemReady;
10048    }
10049
10050    private static File getCalledPreBootReceiversFile() {
10051        File dataDir = Environment.getDataDirectory();
10052        File systemDir = new File(dataDir, "system");
10053        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10054        return fname;
10055    }
10056
10057    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10058        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10059        File file = getCalledPreBootReceiversFile();
10060        FileInputStream fis = null;
10061        try {
10062            fis = new FileInputStream(file);
10063            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10064            int fvers = dis.readInt();
10065            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10066                String vers = dis.readUTF();
10067                String codename = dis.readUTF();
10068                String build = dis.readUTF();
10069                if (android.os.Build.VERSION.RELEASE.equals(vers)
10070                        && android.os.Build.VERSION.CODENAME.equals(codename)
10071                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10072                    int num = dis.readInt();
10073                    while (num > 0) {
10074                        num--;
10075                        String pkg = dis.readUTF();
10076                        String cls = dis.readUTF();
10077                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10078                    }
10079                }
10080            }
10081        } catch (FileNotFoundException e) {
10082        } catch (IOException e) {
10083            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10084        } finally {
10085            if (fis != null) {
10086                try {
10087                    fis.close();
10088                } catch (IOException e) {
10089                }
10090            }
10091        }
10092        return lastDoneReceivers;
10093    }
10094
10095    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10096        File file = getCalledPreBootReceiversFile();
10097        FileOutputStream fos = null;
10098        DataOutputStream dos = null;
10099        try {
10100            fos = new FileOutputStream(file);
10101            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10102            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10103            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10104            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10105            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10106            dos.writeInt(list.size());
10107            for (int i=0; i<list.size(); i++) {
10108                dos.writeUTF(list.get(i).getPackageName());
10109                dos.writeUTF(list.get(i).getClassName());
10110            }
10111        } catch (IOException e) {
10112            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10113            file.delete();
10114        } finally {
10115            FileUtils.sync(fos);
10116            if (dos != null) {
10117                try {
10118                    dos.close();
10119                } catch (IOException e) {
10120                    // TODO Auto-generated catch block
10121                    e.printStackTrace();
10122                }
10123            }
10124        }
10125    }
10126
10127    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10128            ArrayList<ComponentName> doneReceivers, int userId) {
10129        boolean waitingUpdate = false;
10130        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10131        List<ResolveInfo> ris = null;
10132        try {
10133            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10134                    intent, null, 0, userId);
10135        } catch (RemoteException e) {
10136        }
10137        if (ris != null) {
10138            for (int i=ris.size()-1; i>=0; i--) {
10139                if ((ris.get(i).activityInfo.applicationInfo.flags
10140                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10141                    ris.remove(i);
10142                }
10143            }
10144            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10145
10146            // For User 0, load the version number. When delivering to a new user, deliver
10147            // to all receivers.
10148            if (userId == UserHandle.USER_OWNER) {
10149                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10150                for (int i=0; i<ris.size(); i++) {
10151                    ActivityInfo ai = ris.get(i).activityInfo;
10152                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10153                    if (lastDoneReceivers.contains(comp)) {
10154                        // We already did the pre boot receiver for this app with the current
10155                        // platform version, so don't do it again...
10156                        ris.remove(i);
10157                        i--;
10158                        // ...however, do keep it as one that has been done, so we don't
10159                        // forget about it when rewriting the file of last done receivers.
10160                        doneReceivers.add(comp);
10161                    }
10162                }
10163            }
10164
10165            // If primary user, send broadcast to all available users, else just to userId
10166            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10167                    : new int[] { userId };
10168            for (int i = 0; i < ris.size(); i++) {
10169                ActivityInfo ai = ris.get(i).activityInfo;
10170                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10171                doneReceivers.add(comp);
10172                intent.setComponent(comp);
10173                for (int j=0; j<users.length; j++) {
10174                    IIntentReceiver finisher = null;
10175                    // On last receiver and user, set up a completion callback
10176                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10177                        finisher = new IIntentReceiver.Stub() {
10178                            public void performReceive(Intent intent, int resultCode,
10179                                    String data, Bundle extras, boolean ordered,
10180                                    boolean sticky, int sendingUser) {
10181                                // The raw IIntentReceiver interface is called
10182                                // with the AM lock held, so redispatch to
10183                                // execute our code without the lock.
10184                                mHandler.post(onFinishCallback);
10185                            }
10186                        };
10187                    }
10188                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10189                            + " for user " + users[j]);
10190                    broadcastIntentLocked(null, null, intent, null, finisher,
10191                            0, null, null, null, AppOpsManager.OP_NONE,
10192                            true, false, MY_PID, Process.SYSTEM_UID,
10193                            users[j]);
10194                    if (finisher != null) {
10195                        waitingUpdate = true;
10196                    }
10197                }
10198            }
10199        }
10200
10201        return waitingUpdate;
10202    }
10203
10204    public void systemReady(final Runnable goingCallback) {
10205        synchronized(this) {
10206            if (mSystemReady) {
10207                // If we're done calling all the receivers, run the next "boot phase" passed in
10208                // by the SystemServer
10209                if (goingCallback != null) {
10210                    goingCallback.run();
10211                }
10212                return;
10213            }
10214
10215            // Make sure we have the current profile info, since it is needed for
10216            // security checks.
10217            updateCurrentProfileIdsLocked();
10218
10219            if (mRecentTasks == null) {
10220                mRecentTasks = mTaskPersister.restoreTasksLocked();
10221                if (!mRecentTasks.isEmpty()) {
10222                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10223                }
10224                mTaskPersister.startPersisting();
10225            }
10226
10227            // Check to see if there are any update receivers to run.
10228            if (!mDidUpdate) {
10229                if (mWaitingUpdate) {
10230                    return;
10231                }
10232                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10233                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10234                    public void run() {
10235                        synchronized (ActivityManagerService.this) {
10236                            mDidUpdate = true;
10237                        }
10238                        writeLastDonePreBootReceivers(doneReceivers);
10239                        showBootMessage(mContext.getText(
10240                                R.string.android_upgrading_complete),
10241                                false);
10242                        systemReady(goingCallback);
10243                    }
10244                }, doneReceivers, UserHandle.USER_OWNER);
10245
10246                if (mWaitingUpdate) {
10247                    return;
10248                }
10249                mDidUpdate = true;
10250            }
10251
10252            mAppOpsService.systemReady();
10253            mSystemReady = true;
10254        }
10255
10256        ArrayList<ProcessRecord> procsToKill = null;
10257        synchronized(mPidsSelfLocked) {
10258            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10259                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10260                if (!isAllowedWhileBooting(proc.info)){
10261                    if (procsToKill == null) {
10262                        procsToKill = new ArrayList<ProcessRecord>();
10263                    }
10264                    procsToKill.add(proc);
10265                }
10266            }
10267        }
10268
10269        synchronized(this) {
10270            if (procsToKill != null) {
10271                for (int i=procsToKill.size()-1; i>=0; i--) {
10272                    ProcessRecord proc = procsToKill.get(i);
10273                    Slog.i(TAG, "Removing system update proc: " + proc);
10274                    removeProcessLocked(proc, true, false, "system update done");
10275                }
10276            }
10277
10278            // Now that we have cleaned up any update processes, we
10279            // are ready to start launching real processes and know that
10280            // we won't trample on them any more.
10281            mProcessesReady = true;
10282        }
10283
10284        Slog.i(TAG, "System now ready");
10285        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10286            SystemClock.uptimeMillis());
10287
10288        synchronized(this) {
10289            // Make sure we have no pre-ready processes sitting around.
10290
10291            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10292                ResolveInfo ri = mContext.getPackageManager()
10293                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10294                                STOCK_PM_FLAGS);
10295                CharSequence errorMsg = null;
10296                if (ri != null) {
10297                    ActivityInfo ai = ri.activityInfo;
10298                    ApplicationInfo app = ai.applicationInfo;
10299                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10300                        mTopAction = Intent.ACTION_FACTORY_TEST;
10301                        mTopData = null;
10302                        mTopComponent = new ComponentName(app.packageName,
10303                                ai.name);
10304                    } else {
10305                        errorMsg = mContext.getResources().getText(
10306                                com.android.internal.R.string.factorytest_not_system);
10307                    }
10308                } else {
10309                    errorMsg = mContext.getResources().getText(
10310                            com.android.internal.R.string.factorytest_no_action);
10311                }
10312                if (errorMsg != null) {
10313                    mTopAction = null;
10314                    mTopData = null;
10315                    mTopComponent = null;
10316                    Message msg = Message.obtain();
10317                    msg.what = SHOW_FACTORY_ERROR_MSG;
10318                    msg.getData().putCharSequence("msg", errorMsg);
10319                    mHandler.sendMessage(msg);
10320                }
10321            }
10322        }
10323
10324        retrieveSettings();
10325
10326        synchronized (this) {
10327            readGrantedUriPermissionsLocked();
10328        }
10329
10330        if (goingCallback != null) goingCallback.run();
10331
10332        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
10333                Integer.toString(mCurrentUserId), mCurrentUserId);
10334        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
10335                Integer.toString(mCurrentUserId), mCurrentUserId);
10336        mSystemServiceManager.startUser(mCurrentUserId);
10337
10338        synchronized (this) {
10339            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10340                try {
10341                    List apps = AppGlobals.getPackageManager().
10342                        getPersistentApplications(STOCK_PM_FLAGS);
10343                    if (apps != null) {
10344                        int N = apps.size();
10345                        int i;
10346                        for (i=0; i<N; i++) {
10347                            ApplicationInfo info
10348                                = (ApplicationInfo)apps.get(i);
10349                            if (info != null &&
10350                                    !info.packageName.equals("android")) {
10351                                addAppLocked(info, false, null /* ABI override */);
10352                            }
10353                        }
10354                    }
10355                } catch (RemoteException ex) {
10356                    // pm is in same process, this will never happen.
10357                }
10358            }
10359
10360            // Start up initial activity.
10361            mBooting = true;
10362
10363            try {
10364                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
10365                    Message msg = Message.obtain();
10366                    msg.what = SHOW_UID_ERROR_MSG;
10367                    mHandler.sendMessage(msg);
10368                }
10369            } catch (RemoteException e) {
10370            }
10371
10372            long ident = Binder.clearCallingIdentity();
10373            try {
10374                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
10375                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
10376                        | Intent.FLAG_RECEIVER_FOREGROUND);
10377                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10378                broadcastIntentLocked(null, null, intent,
10379                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
10380                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
10381                intent = new Intent(Intent.ACTION_USER_STARTING);
10382                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
10383                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
10384                broadcastIntentLocked(null, null, intent,
10385                        null, new IIntentReceiver.Stub() {
10386                            @Override
10387                            public void performReceive(Intent intent, int resultCode, String data,
10388                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
10389                                    throws RemoteException {
10390                            }
10391                        }, 0, null, null,
10392                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
10393                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
10394            } catch (Throwable t) {
10395                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
10396            } finally {
10397                Binder.restoreCallingIdentity(ident);
10398            }
10399            mStackSupervisor.resumeTopActivitiesLocked();
10400            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
10401        }
10402    }
10403
10404    private boolean makeAppCrashingLocked(ProcessRecord app,
10405            String shortMsg, String longMsg, String stackTrace) {
10406        app.crashing = true;
10407        app.crashingReport = generateProcessError(app,
10408                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
10409        startAppProblemLocked(app);
10410        app.stopFreezingAllLocked();
10411        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
10412    }
10413
10414    private void makeAppNotRespondingLocked(ProcessRecord app,
10415            String activity, String shortMsg, String longMsg) {
10416        app.notResponding = true;
10417        app.notRespondingReport = generateProcessError(app,
10418                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
10419                activity, shortMsg, longMsg, null);
10420        startAppProblemLocked(app);
10421        app.stopFreezingAllLocked();
10422    }
10423
10424    /**
10425     * Generate a process error record, suitable for attachment to a ProcessRecord.
10426     *
10427     * @param app The ProcessRecord in which the error occurred.
10428     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
10429     *                      ActivityManager.AppErrorStateInfo
10430     * @param activity The activity associated with the crash, if known.
10431     * @param shortMsg Short message describing the crash.
10432     * @param longMsg Long message describing the crash.
10433     * @param stackTrace Full crash stack trace, may be null.
10434     *
10435     * @return Returns a fully-formed AppErrorStateInfo record.
10436     */
10437    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
10438            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
10439        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
10440
10441        report.condition = condition;
10442        report.processName = app.processName;
10443        report.pid = app.pid;
10444        report.uid = app.info.uid;
10445        report.tag = activity;
10446        report.shortMsg = shortMsg;
10447        report.longMsg = longMsg;
10448        report.stackTrace = stackTrace;
10449
10450        return report;
10451    }
10452
10453    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
10454        synchronized (this) {
10455            app.crashing = false;
10456            app.crashingReport = null;
10457            app.notResponding = false;
10458            app.notRespondingReport = null;
10459            if (app.anrDialog == fromDialog) {
10460                app.anrDialog = null;
10461            }
10462            if (app.waitDialog == fromDialog) {
10463                app.waitDialog = null;
10464            }
10465            if (app.pid > 0 && app.pid != MY_PID) {
10466                handleAppCrashLocked(app, null, null, null);
10467                killUnneededProcessLocked(app, "user request after error");
10468            }
10469        }
10470    }
10471
10472    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
10473            String stackTrace) {
10474        long now = SystemClock.uptimeMillis();
10475
10476        Long crashTime;
10477        if (!app.isolated) {
10478            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
10479        } else {
10480            crashTime = null;
10481        }
10482        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
10483            // This process loses!
10484            Slog.w(TAG, "Process " + app.info.processName
10485                    + " has crashed too many times: killing!");
10486            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
10487                    app.userId, app.info.processName, app.uid);
10488            mStackSupervisor.handleAppCrashLocked(app);
10489            if (!app.persistent) {
10490                // We don't want to start this process again until the user
10491                // explicitly does so...  but for persistent process, we really
10492                // need to keep it running.  If a persistent process is actually
10493                // repeatedly crashing, then badness for everyone.
10494                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
10495                        app.info.processName);
10496                if (!app.isolated) {
10497                    // XXX We don't have a way to mark isolated processes
10498                    // as bad, since they don't have a peristent identity.
10499                    mBadProcesses.put(app.info.processName, app.uid,
10500                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
10501                    mProcessCrashTimes.remove(app.info.processName, app.uid);
10502                }
10503                app.bad = true;
10504                app.removed = true;
10505                // Don't let services in this process be restarted and potentially
10506                // annoy the user repeatedly.  Unless it is persistent, since those
10507                // processes run critical code.
10508                removeProcessLocked(app, false, false, "crash");
10509                mStackSupervisor.resumeTopActivitiesLocked();
10510                return false;
10511            }
10512            mStackSupervisor.resumeTopActivitiesLocked();
10513        } else {
10514            mStackSupervisor.finishTopRunningActivityLocked(app);
10515        }
10516
10517        // Bump up the crash count of any services currently running in the proc.
10518        for (int i=app.services.size()-1; i>=0; i--) {
10519            // Any services running in the application need to be placed
10520            // back in the pending list.
10521            ServiceRecord sr = app.services.valueAt(i);
10522            sr.crashCount++;
10523        }
10524
10525        // If the crashing process is what we consider to be the "home process" and it has been
10526        // replaced by a third-party app, clear the package preferred activities from packages
10527        // with a home activity running in the process to prevent a repeatedly crashing app
10528        // from blocking the user to manually clear the list.
10529        final ArrayList<ActivityRecord> activities = app.activities;
10530        if (app == mHomeProcess && activities.size() > 0
10531                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
10532            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
10533                final ActivityRecord r = activities.get(activityNdx);
10534                if (r.isHomeActivity()) {
10535                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
10536                    try {
10537                        ActivityThread.getPackageManager()
10538                                .clearPackagePreferredActivities(r.packageName);
10539                    } catch (RemoteException c) {
10540                        // pm is in same process, this will never happen.
10541                    }
10542                }
10543            }
10544        }
10545
10546        if (!app.isolated) {
10547            // XXX Can't keep track of crash times for isolated processes,
10548            // because they don't have a perisistent identity.
10549            mProcessCrashTimes.put(app.info.processName, app.uid, now);
10550        }
10551
10552        if (app.crashHandler != null) mHandler.post(app.crashHandler);
10553        return true;
10554    }
10555
10556    void startAppProblemLocked(ProcessRecord app) {
10557        if (app.userId == mCurrentUserId) {
10558            app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
10559                    mContext, app.info.packageName, app.info.flags);
10560        } else {
10561            // If this app is not running under the current user, then we
10562            // can't give it a report button because that would require
10563            // launching the report UI under a different user.
10564            app.errorReportReceiver = null;
10565        }
10566        skipCurrentReceiverLocked(app);
10567    }
10568
10569    void skipCurrentReceiverLocked(ProcessRecord app) {
10570        for (BroadcastQueue queue : mBroadcastQueues) {
10571            queue.skipCurrentReceiverLocked(app);
10572        }
10573    }
10574
10575    /**
10576     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
10577     * The application process will exit immediately after this call returns.
10578     * @param app object of the crashing app, null for the system server
10579     * @param crashInfo describing the exception
10580     */
10581    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
10582        ProcessRecord r = findAppProcess(app, "Crash");
10583        final String processName = app == null ? "system_server"
10584                : (r == null ? "unknown" : r.processName);
10585
10586        handleApplicationCrashInner("crash", r, processName, crashInfo);
10587    }
10588
10589    /* Native crash reporting uses this inner version because it needs to be somewhat
10590     * decoupled from the AM-managed cleanup lifecycle
10591     */
10592    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
10593            ApplicationErrorReport.CrashInfo crashInfo) {
10594        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
10595                UserHandle.getUserId(Binder.getCallingUid()), processName,
10596                r == null ? -1 : r.info.flags,
10597                crashInfo.exceptionClassName,
10598                crashInfo.exceptionMessage,
10599                crashInfo.throwFileName,
10600                crashInfo.throwLineNumber);
10601
10602        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
10603
10604        crashApplication(r, crashInfo);
10605    }
10606
10607    public void handleApplicationStrictModeViolation(
10608            IBinder app,
10609            int violationMask,
10610            StrictMode.ViolationInfo info) {
10611        ProcessRecord r = findAppProcess(app, "StrictMode");
10612        if (r == null) {
10613            return;
10614        }
10615
10616        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
10617            Integer stackFingerprint = info.hashCode();
10618            boolean logIt = true;
10619            synchronized (mAlreadyLoggedViolatedStacks) {
10620                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
10621                    logIt = false;
10622                    // TODO: sub-sample into EventLog for these, with
10623                    // the info.durationMillis?  Then we'd get
10624                    // the relative pain numbers, without logging all
10625                    // the stack traces repeatedly.  We'd want to do
10626                    // likewise in the client code, which also does
10627                    // dup suppression, before the Binder call.
10628                } else {
10629                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
10630                        mAlreadyLoggedViolatedStacks.clear();
10631                    }
10632                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
10633                }
10634            }
10635            if (logIt) {
10636                logStrictModeViolationToDropBox(r, info);
10637            }
10638        }
10639
10640        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
10641            AppErrorResult result = new AppErrorResult();
10642            synchronized (this) {
10643                final long origId = Binder.clearCallingIdentity();
10644
10645                Message msg = Message.obtain();
10646                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
10647                HashMap<String, Object> data = new HashMap<String, Object>();
10648                data.put("result", result);
10649                data.put("app", r);
10650                data.put("violationMask", violationMask);
10651                data.put("info", info);
10652                msg.obj = data;
10653                mHandler.sendMessage(msg);
10654
10655                Binder.restoreCallingIdentity(origId);
10656            }
10657            int res = result.get();
10658            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
10659        }
10660    }
10661
10662    // Depending on the policy in effect, there could be a bunch of
10663    // these in quick succession so we try to batch these together to
10664    // minimize disk writes, number of dropbox entries, and maximize
10665    // compression, by having more fewer, larger records.
10666    private void logStrictModeViolationToDropBox(
10667            ProcessRecord process,
10668            StrictMode.ViolationInfo info) {
10669        if (info == null) {
10670            return;
10671        }
10672        final boolean isSystemApp = process == null ||
10673                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
10674                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
10675        final String processName = process == null ? "unknown" : process.processName;
10676        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
10677        final DropBoxManager dbox = (DropBoxManager)
10678                mContext.getSystemService(Context.DROPBOX_SERVICE);
10679
10680        // Exit early if the dropbox isn't configured to accept this report type.
10681        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10682
10683        boolean bufferWasEmpty;
10684        boolean needsFlush;
10685        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
10686        synchronized (sb) {
10687            bufferWasEmpty = sb.length() == 0;
10688            appendDropBoxProcessHeaders(process, processName, sb);
10689            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10690            sb.append("System-App: ").append(isSystemApp).append("\n");
10691            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
10692            if (info.violationNumThisLoop != 0) {
10693                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
10694            }
10695            if (info.numAnimationsRunning != 0) {
10696                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
10697            }
10698            if (info.broadcastIntentAction != null) {
10699                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
10700            }
10701            if (info.durationMillis != -1) {
10702                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
10703            }
10704            if (info.numInstances != -1) {
10705                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
10706            }
10707            if (info.tags != null) {
10708                for (String tag : info.tags) {
10709                    sb.append("Span-Tag: ").append(tag).append("\n");
10710                }
10711            }
10712            sb.append("\n");
10713            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
10714                sb.append(info.crashInfo.stackTrace);
10715            }
10716            sb.append("\n");
10717
10718            // Only buffer up to ~64k.  Various logging bits truncate
10719            // things at 128k.
10720            needsFlush = (sb.length() > 64 * 1024);
10721        }
10722
10723        // Flush immediately if the buffer's grown too large, or this
10724        // is a non-system app.  Non-system apps are isolated with a
10725        // different tag & policy and not batched.
10726        //
10727        // Batching is useful during internal testing with
10728        // StrictMode settings turned up high.  Without batching,
10729        // thousands of separate files could be created on boot.
10730        if (!isSystemApp || needsFlush) {
10731            new Thread("Error dump: " + dropboxTag) {
10732                @Override
10733                public void run() {
10734                    String report;
10735                    synchronized (sb) {
10736                        report = sb.toString();
10737                        sb.delete(0, sb.length());
10738                        sb.trimToSize();
10739                    }
10740                    if (report.length() != 0) {
10741                        dbox.addText(dropboxTag, report);
10742                    }
10743                }
10744            }.start();
10745            return;
10746        }
10747
10748        // System app batching:
10749        if (!bufferWasEmpty) {
10750            // An existing dropbox-writing thread is outstanding, so
10751            // we don't need to start it up.  The existing thread will
10752            // catch the buffer appends we just did.
10753            return;
10754        }
10755
10756        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
10757        // (After this point, we shouldn't access AMS internal data structures.)
10758        new Thread("Error dump: " + dropboxTag) {
10759            @Override
10760            public void run() {
10761                // 5 second sleep to let stacks arrive and be batched together
10762                try {
10763                    Thread.sleep(5000);  // 5 seconds
10764                } catch (InterruptedException e) {}
10765
10766                String errorReport;
10767                synchronized (mStrictModeBuffer) {
10768                    errorReport = mStrictModeBuffer.toString();
10769                    if (errorReport.length() == 0) {
10770                        return;
10771                    }
10772                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
10773                    mStrictModeBuffer.trimToSize();
10774                }
10775                dbox.addText(dropboxTag, errorReport);
10776            }
10777        }.start();
10778    }
10779
10780    /**
10781     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
10782     * @param app object of the crashing app, null for the system server
10783     * @param tag reported by the caller
10784     * @param crashInfo describing the context of the error
10785     * @return true if the process should exit immediately (WTF is fatal)
10786     */
10787    public boolean handleApplicationWtf(IBinder app, String tag,
10788            ApplicationErrorReport.CrashInfo crashInfo) {
10789        ProcessRecord r = findAppProcess(app, "WTF");
10790        final String processName = app == null ? "system_server"
10791                : (r == null ? "unknown" : r.processName);
10792
10793        EventLog.writeEvent(EventLogTags.AM_WTF,
10794                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
10795                processName,
10796                r == null ? -1 : r.info.flags,
10797                tag, crashInfo.exceptionMessage);
10798
10799        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
10800
10801        if (r != null && r.pid != Process.myPid() &&
10802                Settings.Global.getInt(mContext.getContentResolver(),
10803                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
10804            crashApplication(r, crashInfo);
10805            return true;
10806        } else {
10807            return false;
10808        }
10809    }
10810
10811    /**
10812     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
10813     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
10814     */
10815    private ProcessRecord findAppProcess(IBinder app, String reason) {
10816        if (app == null) {
10817            return null;
10818        }
10819
10820        synchronized (this) {
10821            final int NP = mProcessNames.getMap().size();
10822            for (int ip=0; ip<NP; ip++) {
10823                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10824                final int NA = apps.size();
10825                for (int ia=0; ia<NA; ia++) {
10826                    ProcessRecord p = apps.valueAt(ia);
10827                    if (p.thread != null && p.thread.asBinder() == app) {
10828                        return p;
10829                    }
10830                }
10831            }
10832
10833            Slog.w(TAG, "Can't find mystery application for " + reason
10834                    + " from pid=" + Binder.getCallingPid()
10835                    + " uid=" + Binder.getCallingUid() + ": " + app);
10836            return null;
10837        }
10838    }
10839
10840    /**
10841     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
10842     * to append various headers to the dropbox log text.
10843     */
10844    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
10845            StringBuilder sb) {
10846        // Watchdog thread ends up invoking this function (with
10847        // a null ProcessRecord) to add the stack file to dropbox.
10848        // Do not acquire a lock on this (am) in such cases, as it
10849        // could cause a potential deadlock, if and when watchdog
10850        // is invoked due to unavailability of lock on am and it
10851        // would prevent watchdog from killing system_server.
10852        if (process == null) {
10853            sb.append("Process: ").append(processName).append("\n");
10854            return;
10855        }
10856        // Note: ProcessRecord 'process' is guarded by the service
10857        // instance.  (notably process.pkgList, which could otherwise change
10858        // concurrently during execution of this method)
10859        synchronized (this) {
10860            sb.append("Process: ").append(processName).append("\n");
10861            int flags = process.info.flags;
10862            IPackageManager pm = AppGlobals.getPackageManager();
10863            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
10864            for (int ip=0; ip<process.pkgList.size(); ip++) {
10865                String pkg = process.pkgList.keyAt(ip);
10866                sb.append("Package: ").append(pkg);
10867                try {
10868                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
10869                    if (pi != null) {
10870                        sb.append(" v").append(pi.versionCode);
10871                        if (pi.versionName != null) {
10872                            sb.append(" (").append(pi.versionName).append(")");
10873                        }
10874                    }
10875                } catch (RemoteException e) {
10876                    Slog.e(TAG, "Error getting package info: " + pkg, e);
10877                }
10878                sb.append("\n");
10879            }
10880        }
10881    }
10882
10883    private static String processClass(ProcessRecord process) {
10884        if (process == null || process.pid == MY_PID) {
10885            return "system_server";
10886        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
10887            return "system_app";
10888        } else {
10889            return "data_app";
10890        }
10891    }
10892
10893    /**
10894     * Write a description of an error (crash, WTF, ANR) to the drop box.
10895     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
10896     * @param process which caused the error, null means the system server
10897     * @param activity which triggered the error, null if unknown
10898     * @param parent activity related to the error, null if unknown
10899     * @param subject line related to the error, null if absent
10900     * @param report in long form describing the error, null if absent
10901     * @param logFile to include in the report, null if none
10902     * @param crashInfo giving an application stack trace, null if absent
10903     */
10904    public void addErrorToDropBox(String eventType,
10905            ProcessRecord process, String processName, ActivityRecord activity,
10906            ActivityRecord parent, String subject,
10907            final String report, final File logFile,
10908            final ApplicationErrorReport.CrashInfo crashInfo) {
10909        // NOTE -- this must never acquire the ActivityManagerService lock,
10910        // otherwise the watchdog may be prevented from resetting the system.
10911
10912        final String dropboxTag = processClass(process) + "_" + eventType;
10913        final DropBoxManager dbox = (DropBoxManager)
10914                mContext.getSystemService(Context.DROPBOX_SERVICE);
10915
10916        // Exit early if the dropbox isn't configured to accept this report type.
10917        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
10918
10919        final StringBuilder sb = new StringBuilder(1024);
10920        appendDropBoxProcessHeaders(process, processName, sb);
10921        if (activity != null) {
10922            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
10923        }
10924        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
10925            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
10926        }
10927        if (parent != null && parent != activity) {
10928            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
10929        }
10930        if (subject != null) {
10931            sb.append("Subject: ").append(subject).append("\n");
10932        }
10933        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
10934        if (Debug.isDebuggerConnected()) {
10935            sb.append("Debugger: Connected\n");
10936        }
10937        sb.append("\n");
10938
10939        // Do the rest in a worker thread to avoid blocking the caller on I/O
10940        // (After this point, we shouldn't access AMS internal data structures.)
10941        Thread worker = new Thread("Error dump: " + dropboxTag) {
10942            @Override
10943            public void run() {
10944                if (report != null) {
10945                    sb.append(report);
10946                }
10947                if (logFile != null) {
10948                    try {
10949                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
10950                                    "\n\n[[TRUNCATED]]"));
10951                    } catch (IOException e) {
10952                        Slog.e(TAG, "Error reading " + logFile, e);
10953                    }
10954                }
10955                if (crashInfo != null && crashInfo.stackTrace != null) {
10956                    sb.append(crashInfo.stackTrace);
10957                }
10958
10959                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
10960                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
10961                if (lines > 0) {
10962                    sb.append("\n");
10963
10964                    // Merge several logcat streams, and take the last N lines
10965                    InputStreamReader input = null;
10966                    try {
10967                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
10968                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
10969                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
10970
10971                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
10972                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
10973                        input = new InputStreamReader(logcat.getInputStream());
10974
10975                        int num;
10976                        char[] buf = new char[8192];
10977                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
10978                    } catch (IOException e) {
10979                        Slog.e(TAG, "Error running logcat", e);
10980                    } finally {
10981                        if (input != null) try { input.close(); } catch (IOException e) {}
10982                    }
10983                }
10984
10985                dbox.addText(dropboxTag, sb.toString());
10986            }
10987        };
10988
10989        if (process == null) {
10990            // If process is null, we are being called from some internal code
10991            // and may be about to die -- run this synchronously.
10992            worker.run();
10993        } else {
10994            worker.start();
10995        }
10996    }
10997
10998    /**
10999     * Bring up the "unexpected error" dialog box for a crashing app.
11000     * Deal with edge cases (intercepts from instrumented applications,
11001     * ActivityController, error intent receivers, that sort of thing).
11002     * @param r the application crashing
11003     * @param crashInfo describing the failure
11004     */
11005    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11006        long timeMillis = System.currentTimeMillis();
11007        String shortMsg = crashInfo.exceptionClassName;
11008        String longMsg = crashInfo.exceptionMessage;
11009        String stackTrace = crashInfo.stackTrace;
11010        if (shortMsg != null && longMsg != null) {
11011            longMsg = shortMsg + ": " + longMsg;
11012        } else if (shortMsg != null) {
11013            longMsg = shortMsg;
11014        }
11015
11016        AppErrorResult result = new AppErrorResult();
11017        synchronized (this) {
11018            if (mController != null) {
11019                try {
11020                    String name = r != null ? r.processName : null;
11021                    int pid = r != null ? r.pid : Binder.getCallingPid();
11022                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11023                    if (!mController.appCrashed(name, pid,
11024                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11025                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11026                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11027                            Slog.w(TAG, "Skip killing native crashed app " + name
11028                                    + "(" + pid + ") during testing");
11029                        } else {
11030                            Slog.w(TAG, "Force-killing crashed app " + name
11031                                    + " at watcher's request");
11032                            Process.killProcess(pid);
11033                            if (r != null) {
11034                                Process.killProcessGroup(uid, pid);
11035                            }
11036                        }
11037                        return;
11038                    }
11039                } catch (RemoteException e) {
11040                    mController = null;
11041                    Watchdog.getInstance().setActivityController(null);
11042                }
11043            }
11044
11045            final long origId = Binder.clearCallingIdentity();
11046
11047            // If this process is running instrumentation, finish it.
11048            if (r != null && r.instrumentationClass != null) {
11049                Slog.w(TAG, "Error in app " + r.processName
11050                      + " running instrumentation " + r.instrumentationClass + ":");
11051                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11052                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11053                Bundle info = new Bundle();
11054                info.putString("shortMsg", shortMsg);
11055                info.putString("longMsg", longMsg);
11056                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11057                Binder.restoreCallingIdentity(origId);
11058                return;
11059            }
11060
11061            // If we can't identify the process or it's already exceeded its crash quota,
11062            // quit right away without showing a crash dialog.
11063            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11064                Binder.restoreCallingIdentity(origId);
11065                return;
11066            }
11067
11068            Message msg = Message.obtain();
11069            msg.what = SHOW_ERROR_MSG;
11070            HashMap data = new HashMap();
11071            data.put("result", result);
11072            data.put("app", r);
11073            msg.obj = data;
11074            mHandler.sendMessage(msg);
11075
11076            Binder.restoreCallingIdentity(origId);
11077        }
11078
11079        int res = result.get();
11080
11081        Intent appErrorIntent = null;
11082        synchronized (this) {
11083            if (r != null && !r.isolated) {
11084                // XXX Can't keep track of crash time for isolated processes,
11085                // since they don't have a persistent identity.
11086                mProcessCrashTimes.put(r.info.processName, r.uid,
11087                        SystemClock.uptimeMillis());
11088            }
11089            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11090                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11091            }
11092        }
11093
11094        if (appErrorIntent != null) {
11095            try {
11096                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11097            } catch (ActivityNotFoundException e) {
11098                Slog.w(TAG, "bug report receiver dissappeared", e);
11099            }
11100        }
11101    }
11102
11103    Intent createAppErrorIntentLocked(ProcessRecord r,
11104            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11105        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11106        if (report == null) {
11107            return null;
11108        }
11109        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11110        result.setComponent(r.errorReportReceiver);
11111        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11112        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11113        return result;
11114    }
11115
11116    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11117            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11118        if (r.errorReportReceiver == null) {
11119            return null;
11120        }
11121
11122        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11123            return null;
11124        }
11125
11126        ApplicationErrorReport report = new ApplicationErrorReport();
11127        report.packageName = r.info.packageName;
11128        report.installerPackageName = r.errorReportReceiver.getPackageName();
11129        report.processName = r.processName;
11130        report.time = timeMillis;
11131        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11132
11133        if (r.crashing || r.forceCrashReport) {
11134            report.type = ApplicationErrorReport.TYPE_CRASH;
11135            report.crashInfo = crashInfo;
11136        } else if (r.notResponding) {
11137            report.type = ApplicationErrorReport.TYPE_ANR;
11138            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11139
11140            report.anrInfo.activity = r.notRespondingReport.tag;
11141            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11142            report.anrInfo.info = r.notRespondingReport.longMsg;
11143        }
11144
11145        return report;
11146    }
11147
11148    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11149        enforceNotIsolatedCaller("getProcessesInErrorState");
11150        // assume our apps are happy - lazy create the list
11151        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11152
11153        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11154                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11155        int userId = UserHandle.getUserId(Binder.getCallingUid());
11156
11157        synchronized (this) {
11158
11159            // iterate across all processes
11160            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11161                ProcessRecord app = mLruProcesses.get(i);
11162                if (!allUsers && app.userId != userId) {
11163                    continue;
11164                }
11165                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11166                    // This one's in trouble, so we'll generate a report for it
11167                    // crashes are higher priority (in case there's a crash *and* an anr)
11168                    ActivityManager.ProcessErrorStateInfo report = null;
11169                    if (app.crashing) {
11170                        report = app.crashingReport;
11171                    } else if (app.notResponding) {
11172                        report = app.notRespondingReport;
11173                    }
11174
11175                    if (report != null) {
11176                        if (errList == null) {
11177                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11178                        }
11179                        errList.add(report);
11180                    } else {
11181                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11182                                " crashing = " + app.crashing +
11183                                " notResponding = " + app.notResponding);
11184                    }
11185                }
11186            }
11187        }
11188
11189        return errList;
11190    }
11191
11192    static int procStateToImportance(int procState, int memAdj,
11193            ActivityManager.RunningAppProcessInfo currApp) {
11194        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11195        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11196            currApp.lru = memAdj;
11197        } else {
11198            currApp.lru = 0;
11199        }
11200        return imp;
11201    }
11202
11203    private void fillInProcMemInfo(ProcessRecord app,
11204            ActivityManager.RunningAppProcessInfo outInfo) {
11205        outInfo.pid = app.pid;
11206        outInfo.uid = app.info.uid;
11207        if (mHeavyWeightProcess == app) {
11208            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11209        }
11210        if (app.persistent) {
11211            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11212        }
11213        if (app.activities.size() > 0) {
11214            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11215        }
11216        outInfo.lastTrimLevel = app.trimMemoryLevel;
11217        int adj = app.curAdj;
11218        int procState = app.curProcState;
11219        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11220        outInfo.importanceReasonCode = app.adjTypeCode;
11221        outInfo.processState = app.curProcState;
11222    }
11223
11224    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11225        enforceNotIsolatedCaller("getRunningAppProcesses");
11226        // Lazy instantiation of list
11227        List<ActivityManager.RunningAppProcessInfo> runList = null;
11228        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11229                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11230        int userId = UserHandle.getUserId(Binder.getCallingUid());
11231        synchronized (this) {
11232            // Iterate across all processes
11233            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11234                ProcessRecord app = mLruProcesses.get(i);
11235                if (!allUsers && app.userId != userId) {
11236                    continue;
11237                }
11238                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11239                    // Generate process state info for running application
11240                    ActivityManager.RunningAppProcessInfo currApp =
11241                        new ActivityManager.RunningAppProcessInfo(app.processName,
11242                                app.pid, app.getPackageList());
11243                    fillInProcMemInfo(app, currApp);
11244                    if (app.adjSource instanceof ProcessRecord) {
11245                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11246                        currApp.importanceReasonImportance =
11247                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11248                                        app.adjSourceProcState);
11249                    } else if (app.adjSource instanceof ActivityRecord) {
11250                        ActivityRecord r = (ActivityRecord)app.adjSource;
11251                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11252                    }
11253                    if (app.adjTarget instanceof ComponentName) {
11254                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11255                    }
11256                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11257                    //        + " lru=" + currApp.lru);
11258                    if (runList == null) {
11259                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11260                    }
11261                    runList.add(currApp);
11262                }
11263            }
11264        }
11265        return runList;
11266    }
11267
11268    public List<ApplicationInfo> getRunningExternalApplications() {
11269        enforceNotIsolatedCaller("getRunningExternalApplications");
11270        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11271        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11272        if (runningApps != null && runningApps.size() > 0) {
11273            Set<String> extList = new HashSet<String>();
11274            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11275                if (app.pkgList != null) {
11276                    for (String pkg : app.pkgList) {
11277                        extList.add(pkg);
11278                    }
11279                }
11280            }
11281            IPackageManager pm = AppGlobals.getPackageManager();
11282            for (String pkg : extList) {
11283                try {
11284                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11285                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11286                        retList.add(info);
11287                    }
11288                } catch (RemoteException e) {
11289                }
11290            }
11291        }
11292        return retList;
11293    }
11294
11295    @Override
11296    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
11297        enforceNotIsolatedCaller("getMyMemoryState");
11298        synchronized (this) {
11299            ProcessRecord proc;
11300            synchronized (mPidsSelfLocked) {
11301                proc = mPidsSelfLocked.get(Binder.getCallingPid());
11302            }
11303            fillInProcMemInfo(proc, outInfo);
11304        }
11305    }
11306
11307    @Override
11308    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
11309        if (checkCallingPermission(android.Manifest.permission.DUMP)
11310                != PackageManager.PERMISSION_GRANTED) {
11311            pw.println("Permission Denial: can't dump ActivityManager from from pid="
11312                    + Binder.getCallingPid()
11313                    + ", uid=" + Binder.getCallingUid()
11314                    + " without permission "
11315                    + android.Manifest.permission.DUMP);
11316            return;
11317        }
11318
11319        boolean dumpAll = false;
11320        boolean dumpClient = false;
11321        String dumpPackage = null;
11322
11323        int opti = 0;
11324        while (opti < args.length) {
11325            String opt = args[opti];
11326            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
11327                break;
11328            }
11329            opti++;
11330            if ("-a".equals(opt)) {
11331                dumpAll = true;
11332            } else if ("-c".equals(opt)) {
11333                dumpClient = true;
11334            } else if ("-h".equals(opt)) {
11335                pw.println("Activity manager dump options:");
11336                pw.println("  [-a] [-c] [-h] [cmd] ...");
11337                pw.println("  cmd may be one of:");
11338                pw.println("    a[ctivities]: activity stack state");
11339                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
11340                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
11341                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
11342                pw.println("    o[om]: out of memory management");
11343                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
11344                pw.println("    provider [COMP_SPEC]: provider client-side state");
11345                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
11346                pw.println("    service [COMP_SPEC]: service client-side state");
11347                pw.println("    package [PACKAGE_NAME]: all state related to given package");
11348                pw.println("    all: dump all activities");
11349                pw.println("    top: dump the top activity");
11350                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
11351                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
11352                pw.println("    a partial substring in a component name, a");
11353                pw.println("    hex object identifier.");
11354                pw.println("  -a: include all available server state.");
11355                pw.println("  -c: include client state.");
11356                return;
11357            } else {
11358                pw.println("Unknown argument: " + opt + "; use -h for help");
11359            }
11360        }
11361
11362        long origId = Binder.clearCallingIdentity();
11363        boolean more = false;
11364        // Is the caller requesting to dump a particular piece of data?
11365        if (opti < args.length) {
11366            String cmd = args[opti];
11367            opti++;
11368            if ("activities".equals(cmd) || "a".equals(cmd)) {
11369                synchronized (this) {
11370                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
11371                }
11372            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
11373                String[] newArgs;
11374                String name;
11375                if (opti >= args.length) {
11376                    name = null;
11377                    newArgs = EMPTY_STRING_ARRAY;
11378                } else {
11379                    name = args[opti];
11380                    opti++;
11381                    newArgs = new String[args.length - opti];
11382                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11383                            args.length - opti);
11384                }
11385                synchronized (this) {
11386                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
11387                }
11388            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
11389                String[] newArgs;
11390                String name;
11391                if (opti >= args.length) {
11392                    name = null;
11393                    newArgs = EMPTY_STRING_ARRAY;
11394                } else {
11395                    name = args[opti];
11396                    opti++;
11397                    newArgs = new String[args.length - opti];
11398                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11399                            args.length - opti);
11400                }
11401                synchronized (this) {
11402                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
11403                }
11404            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
11405                String[] newArgs;
11406                String name;
11407                if (opti >= args.length) {
11408                    name = null;
11409                    newArgs = EMPTY_STRING_ARRAY;
11410                } else {
11411                    name = args[opti];
11412                    opti++;
11413                    newArgs = new String[args.length - opti];
11414                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11415                            args.length - opti);
11416                }
11417                synchronized (this) {
11418                    dumpProcessesLocked(fd, pw, args, opti, true, name);
11419                }
11420            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
11421                synchronized (this) {
11422                    dumpOomLocked(fd, pw, args, opti, true);
11423                }
11424            } else if ("provider".equals(cmd)) {
11425                String[] newArgs;
11426                String name;
11427                if (opti >= args.length) {
11428                    name = null;
11429                    newArgs = EMPTY_STRING_ARRAY;
11430                } else {
11431                    name = args[opti];
11432                    opti++;
11433                    newArgs = new String[args.length - opti];
11434                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
11435                }
11436                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
11437                    pw.println("No providers match: " + name);
11438                    pw.println("Use -h for help.");
11439                }
11440            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
11441                synchronized (this) {
11442                    dumpProvidersLocked(fd, pw, args, opti, true, null);
11443                }
11444            } else if ("service".equals(cmd)) {
11445                String[] newArgs;
11446                String name;
11447                if (opti >= args.length) {
11448                    name = null;
11449                    newArgs = EMPTY_STRING_ARRAY;
11450                } else {
11451                    name = args[opti];
11452                    opti++;
11453                    newArgs = new String[args.length - opti];
11454                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11455                            args.length - opti);
11456                }
11457                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
11458                    pw.println("No services match: " + name);
11459                    pw.println("Use -h for help.");
11460                }
11461            } else if ("package".equals(cmd)) {
11462                String[] newArgs;
11463                if (opti >= args.length) {
11464                    pw.println("package: no package name specified");
11465                    pw.println("Use -h for help.");
11466                } else {
11467                    dumpPackage = args[opti];
11468                    opti++;
11469                    newArgs = new String[args.length - opti];
11470                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
11471                            args.length - opti);
11472                    args = newArgs;
11473                    opti = 0;
11474                    more = true;
11475                }
11476            } else if ("services".equals(cmd) || "s".equals(cmd)) {
11477                synchronized (this) {
11478                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
11479                }
11480            } else {
11481                // Dumping a single activity?
11482                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
11483                    pw.println("Bad activity command, or no activities match: " + cmd);
11484                    pw.println("Use -h for help.");
11485                }
11486            }
11487            if (!more) {
11488                Binder.restoreCallingIdentity(origId);
11489                return;
11490            }
11491        }
11492
11493        // No piece of data specified, dump everything.
11494        synchronized (this) {
11495            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11496            pw.println();
11497            if (dumpAll) {
11498                pw.println("-------------------------------------------------------------------------------");
11499            }
11500            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11501            pw.println();
11502            if (dumpAll) {
11503                pw.println("-------------------------------------------------------------------------------");
11504            }
11505            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11506            pw.println();
11507            if (dumpAll) {
11508                pw.println("-------------------------------------------------------------------------------");
11509            }
11510            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11511            pw.println();
11512            if (dumpAll) {
11513                pw.println("-------------------------------------------------------------------------------");
11514            }
11515            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
11516            pw.println();
11517            if (dumpAll) {
11518                pw.println("-------------------------------------------------------------------------------");
11519            }
11520            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
11521        }
11522        Binder.restoreCallingIdentity(origId);
11523    }
11524
11525    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11526            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
11527        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
11528
11529        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
11530                dumpPackage);
11531        boolean needSep = printedAnything;
11532
11533        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
11534                dumpPackage, needSep, "  mFocusedActivity: ");
11535        if (printed) {
11536            printedAnything = true;
11537            needSep = false;
11538        }
11539
11540        if (dumpPackage == null) {
11541            if (needSep) {
11542                pw.println();
11543            }
11544            needSep = true;
11545            printedAnything = true;
11546            mStackSupervisor.dump(pw, "  ");
11547        }
11548
11549        if (mRecentTasks.size() > 0) {
11550            boolean printedHeader = false;
11551
11552            final int N = mRecentTasks.size();
11553            for (int i=0; i<N; i++) {
11554                TaskRecord tr = mRecentTasks.get(i);
11555                if (dumpPackage != null) {
11556                    if (tr.realActivity == null ||
11557                            !dumpPackage.equals(tr.realActivity)) {
11558                        continue;
11559                    }
11560                }
11561                if (!printedHeader) {
11562                    if (needSep) {
11563                        pw.println();
11564                    }
11565                    pw.println("  Recent tasks:");
11566                    printedHeader = true;
11567                    printedAnything = true;
11568                }
11569                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
11570                        pw.println(tr);
11571                if (dumpAll) {
11572                    mRecentTasks.get(i).dump(pw, "    ");
11573                }
11574            }
11575        }
11576
11577        if (!printedAnything) {
11578            pw.println("  (nothing)");
11579        }
11580    }
11581
11582    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
11583            int opti, boolean dumpAll, String dumpPackage) {
11584        boolean needSep = false;
11585        boolean printedAnything = false;
11586        int numPers = 0;
11587
11588        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
11589
11590        if (dumpAll) {
11591            final int NP = mProcessNames.getMap().size();
11592            for (int ip=0; ip<NP; ip++) {
11593                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
11594                final int NA = procs.size();
11595                for (int ia=0; ia<NA; ia++) {
11596                    ProcessRecord r = procs.valueAt(ia);
11597                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11598                        continue;
11599                    }
11600                    if (!needSep) {
11601                        pw.println("  All known processes:");
11602                        needSep = true;
11603                        printedAnything = true;
11604                    }
11605                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
11606                        pw.print(" UID "); pw.print(procs.keyAt(ia));
11607                        pw.print(" "); pw.println(r);
11608                    r.dump(pw, "    ");
11609                    if (r.persistent) {
11610                        numPers++;
11611                    }
11612                }
11613            }
11614        }
11615
11616        if (mIsolatedProcesses.size() > 0) {
11617            boolean printed = false;
11618            for (int i=0; i<mIsolatedProcesses.size(); i++) {
11619                ProcessRecord r = mIsolatedProcesses.valueAt(i);
11620                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11621                    continue;
11622                }
11623                if (!printed) {
11624                    if (needSep) {
11625                        pw.println();
11626                    }
11627                    pw.println("  Isolated process list (sorted by uid):");
11628                    printedAnything = true;
11629                    printed = true;
11630                    needSep = true;
11631                }
11632                pw.println(String.format("%sIsolated #%2d: %s",
11633                        "    ", i, r.toString()));
11634            }
11635        }
11636
11637        if (mLruProcesses.size() > 0) {
11638            if (needSep) {
11639                pw.println();
11640            }
11641            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
11642                    pw.print(" total, non-act at ");
11643                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
11644                    pw.print(", non-svc at ");
11645                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
11646                    pw.println("):");
11647            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
11648            needSep = true;
11649            printedAnything = true;
11650        }
11651
11652        if (dumpAll || dumpPackage != null) {
11653            synchronized (mPidsSelfLocked) {
11654                boolean printed = false;
11655                for (int i=0; i<mPidsSelfLocked.size(); i++) {
11656                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
11657                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
11658                        continue;
11659                    }
11660                    if (!printed) {
11661                        if (needSep) pw.println();
11662                        needSep = true;
11663                        pw.println("  PID mappings:");
11664                        printed = true;
11665                        printedAnything = true;
11666                    }
11667                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
11668                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
11669                }
11670            }
11671        }
11672
11673        if (mForegroundProcesses.size() > 0) {
11674            synchronized (mPidsSelfLocked) {
11675                boolean printed = false;
11676                for (int i=0; i<mForegroundProcesses.size(); i++) {
11677                    ProcessRecord r = mPidsSelfLocked.get(
11678                            mForegroundProcesses.valueAt(i).pid);
11679                    if (dumpPackage != null && (r == null
11680                            || !r.pkgList.containsKey(dumpPackage))) {
11681                        continue;
11682                    }
11683                    if (!printed) {
11684                        if (needSep) pw.println();
11685                        needSep = true;
11686                        pw.println("  Foreground Processes:");
11687                        printed = true;
11688                        printedAnything = true;
11689                    }
11690                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
11691                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
11692                }
11693            }
11694        }
11695
11696        if (mPersistentStartingProcesses.size() > 0) {
11697            if (needSep) pw.println();
11698            needSep = true;
11699            printedAnything = true;
11700            pw.println("  Persisent processes that are starting:");
11701            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
11702                    "Starting Norm", "Restarting PERS", dumpPackage);
11703        }
11704
11705        if (mRemovedProcesses.size() > 0) {
11706            if (needSep) pw.println();
11707            needSep = true;
11708            printedAnything = true;
11709            pw.println("  Processes that are being removed:");
11710            dumpProcessList(pw, this, mRemovedProcesses, "    ",
11711                    "Removed Norm", "Removed PERS", dumpPackage);
11712        }
11713
11714        if (mProcessesOnHold.size() > 0) {
11715            if (needSep) pw.println();
11716            needSep = true;
11717            printedAnything = true;
11718            pw.println("  Processes that are on old until the system is ready:");
11719            dumpProcessList(pw, this, mProcessesOnHold, "    ",
11720                    "OnHold Norm", "OnHold PERS", dumpPackage);
11721        }
11722
11723        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
11724
11725        if (mProcessCrashTimes.getMap().size() > 0) {
11726            boolean printed = false;
11727            long now = SystemClock.uptimeMillis();
11728            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
11729            final int NP = pmap.size();
11730            for (int ip=0; ip<NP; ip++) {
11731                String pname = pmap.keyAt(ip);
11732                SparseArray<Long> uids = pmap.valueAt(ip);
11733                final int N = uids.size();
11734                for (int i=0; i<N; i++) {
11735                    int puid = uids.keyAt(i);
11736                    ProcessRecord r = mProcessNames.get(pname, puid);
11737                    if (dumpPackage != null && (r == null
11738                            || !r.pkgList.containsKey(dumpPackage))) {
11739                        continue;
11740                    }
11741                    if (!printed) {
11742                        if (needSep) pw.println();
11743                        needSep = true;
11744                        pw.println("  Time since processes crashed:");
11745                        printed = true;
11746                        printedAnything = true;
11747                    }
11748                    pw.print("    Process "); pw.print(pname);
11749                            pw.print(" uid "); pw.print(puid);
11750                            pw.print(": last crashed ");
11751                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
11752                            pw.println(" ago");
11753                }
11754            }
11755        }
11756
11757        if (mBadProcesses.getMap().size() > 0) {
11758            boolean printed = false;
11759            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
11760            final int NP = pmap.size();
11761            for (int ip=0; ip<NP; ip++) {
11762                String pname = pmap.keyAt(ip);
11763                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
11764                final int N = uids.size();
11765                for (int i=0; i<N; i++) {
11766                    int puid = uids.keyAt(i);
11767                    ProcessRecord r = mProcessNames.get(pname, puid);
11768                    if (dumpPackage != null && (r == null
11769                            || !r.pkgList.containsKey(dumpPackage))) {
11770                        continue;
11771                    }
11772                    if (!printed) {
11773                        if (needSep) pw.println();
11774                        needSep = true;
11775                        pw.println("  Bad processes:");
11776                        printedAnything = true;
11777                    }
11778                    BadProcessInfo info = uids.valueAt(i);
11779                    pw.print("    Bad process "); pw.print(pname);
11780                            pw.print(" uid "); pw.print(puid);
11781                            pw.print(": crashed at time "); pw.println(info.time);
11782                    if (info.shortMsg != null) {
11783                        pw.print("      Short msg: "); pw.println(info.shortMsg);
11784                    }
11785                    if (info.longMsg != null) {
11786                        pw.print("      Long msg: "); pw.println(info.longMsg);
11787                    }
11788                    if (info.stack != null) {
11789                        pw.println("      Stack:");
11790                        int lastPos = 0;
11791                        for (int pos=0; pos<info.stack.length(); pos++) {
11792                            if (info.stack.charAt(pos) == '\n') {
11793                                pw.print("        ");
11794                                pw.write(info.stack, lastPos, pos-lastPos);
11795                                pw.println();
11796                                lastPos = pos+1;
11797                            }
11798                        }
11799                        if (lastPos < info.stack.length()) {
11800                            pw.print("        ");
11801                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
11802                            pw.println();
11803                        }
11804                    }
11805                }
11806            }
11807        }
11808
11809        if (dumpPackage == null) {
11810            pw.println();
11811            needSep = false;
11812            pw.println("  mStartedUsers:");
11813            for (int i=0; i<mStartedUsers.size(); i++) {
11814                UserStartedState uss = mStartedUsers.valueAt(i);
11815                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
11816                        pw.print(": "); uss.dump("", pw);
11817            }
11818            pw.print("  mStartedUserArray: [");
11819            for (int i=0; i<mStartedUserArray.length; i++) {
11820                if (i > 0) pw.print(", ");
11821                pw.print(mStartedUserArray[i]);
11822            }
11823            pw.println("]");
11824            pw.print("  mUserLru: [");
11825            for (int i=0; i<mUserLru.size(); i++) {
11826                if (i > 0) pw.print(", ");
11827                pw.print(mUserLru.get(i));
11828            }
11829            pw.println("]");
11830            if (dumpAll) {
11831                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
11832            }
11833            synchronized (mUserProfileGroupIdsSelfLocked) {
11834                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
11835                    pw.println("  mUserProfileGroupIds:");
11836                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
11837                        pw.print("    User #");
11838                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
11839                        pw.print(" -> profile #");
11840                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
11841                    }
11842                }
11843            }
11844        }
11845        if (mHomeProcess != null && (dumpPackage == null
11846                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
11847            if (needSep) {
11848                pw.println();
11849                needSep = false;
11850            }
11851            pw.println("  mHomeProcess: " + mHomeProcess);
11852        }
11853        if (mPreviousProcess != null && (dumpPackage == null
11854                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
11855            if (needSep) {
11856                pw.println();
11857                needSep = false;
11858            }
11859            pw.println("  mPreviousProcess: " + mPreviousProcess);
11860        }
11861        if (dumpAll) {
11862            StringBuilder sb = new StringBuilder(128);
11863            sb.append("  mPreviousProcessVisibleTime: ");
11864            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
11865            pw.println(sb);
11866        }
11867        if (mHeavyWeightProcess != null && (dumpPackage == null
11868                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
11869            if (needSep) {
11870                pw.println();
11871                needSep = false;
11872            }
11873            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
11874        }
11875        if (dumpPackage == null) {
11876            pw.println("  mConfiguration: " + mConfiguration);
11877        }
11878        if (dumpAll) {
11879            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
11880            if (mCompatModePackages.getPackages().size() > 0) {
11881                boolean printed = false;
11882                for (Map.Entry<String, Integer> entry
11883                        : mCompatModePackages.getPackages().entrySet()) {
11884                    String pkg = entry.getKey();
11885                    int mode = entry.getValue();
11886                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
11887                        continue;
11888                    }
11889                    if (!printed) {
11890                        pw.println("  mScreenCompatPackages:");
11891                        printed = true;
11892                    }
11893                    pw.print("    "); pw.print(pkg); pw.print(": ");
11894                            pw.print(mode); pw.println();
11895                }
11896            }
11897        }
11898        if (dumpPackage == null) {
11899            if (mSleeping || mWentToSleep || mLockScreenShown) {
11900                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
11901                        + " mLockScreenShown " + mLockScreenShown);
11902            }
11903            if (mShuttingDown || mRunningVoice) {
11904                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
11905            }
11906        }
11907        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
11908                || mOrigWaitForDebugger) {
11909            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
11910                    || dumpPackage.equals(mOrigDebugApp)) {
11911                if (needSep) {
11912                    pw.println();
11913                    needSep = false;
11914                }
11915                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
11916                        + " mDebugTransient=" + mDebugTransient
11917                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
11918            }
11919        }
11920        if (mOpenGlTraceApp != null) {
11921            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
11922                if (needSep) {
11923                    pw.println();
11924                    needSep = false;
11925                }
11926                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
11927            }
11928        }
11929        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
11930                || mProfileFd != null) {
11931            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
11932                if (needSep) {
11933                    pw.println();
11934                    needSep = false;
11935                }
11936                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
11937                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
11938                pw.println("  mProfileType=" + mProfileType + " mAutoStopProfiler="
11939                        + mAutoStopProfiler);
11940            }
11941        }
11942        if (dumpPackage == null) {
11943            if (mAlwaysFinishActivities || mController != null) {
11944                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
11945                        + " mController=" + mController);
11946            }
11947            if (dumpAll) {
11948                pw.println("  Total persistent processes: " + numPers);
11949                pw.println("  mProcessesReady=" + mProcessesReady
11950                        + " mSystemReady=" + mSystemReady);
11951                pw.println("  mBooting=" + mBooting
11952                        + " mBooted=" + mBooted
11953                        + " mFactoryTest=" + mFactoryTest);
11954                pw.print("  mLastPowerCheckRealtime=");
11955                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
11956                        pw.println("");
11957                pw.print("  mLastPowerCheckUptime=");
11958                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
11959                        pw.println("");
11960                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
11961                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
11962                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
11963                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
11964                        + " (" + mLruProcesses.size() + " total)"
11965                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
11966                        + " mNumServiceProcs=" + mNumServiceProcs
11967                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
11968                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
11969                        + " mLastMemoryLevel" + mLastMemoryLevel
11970                        + " mLastNumProcesses" + mLastNumProcesses);
11971                long now = SystemClock.uptimeMillis();
11972                pw.print("  mLastIdleTime=");
11973                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
11974                        pw.print(" mLowRamSinceLastIdle=");
11975                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
11976                        pw.println();
11977            }
11978        }
11979
11980        if (!printedAnything) {
11981            pw.println("  (nothing)");
11982        }
11983    }
11984
11985    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
11986            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
11987        if (mProcessesToGc.size() > 0) {
11988            boolean printed = false;
11989            long now = SystemClock.uptimeMillis();
11990            for (int i=0; i<mProcessesToGc.size(); i++) {
11991                ProcessRecord proc = mProcessesToGc.get(i);
11992                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
11993                    continue;
11994                }
11995                if (!printed) {
11996                    if (needSep) pw.println();
11997                    needSep = true;
11998                    pw.println("  Processes that are waiting to GC:");
11999                    printed = true;
12000                }
12001                pw.print("    Process "); pw.println(proc);
12002                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12003                        pw.print(", last gced=");
12004                        pw.print(now-proc.lastRequestedGc);
12005                        pw.print(" ms ago, last lowMem=");
12006                        pw.print(now-proc.lastLowMemory);
12007                        pw.println(" ms ago");
12008
12009            }
12010        }
12011        return needSep;
12012    }
12013
12014    void printOomLevel(PrintWriter pw, String name, int adj) {
12015        pw.print("    ");
12016        if (adj >= 0) {
12017            pw.print(' ');
12018            if (adj < 10) pw.print(' ');
12019        } else {
12020            if (adj > -10) pw.print(' ');
12021        }
12022        pw.print(adj);
12023        pw.print(": ");
12024        pw.print(name);
12025        pw.print(" (");
12026        pw.print(mProcessList.getMemLevel(adj)/1024);
12027        pw.println(" kB)");
12028    }
12029
12030    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12031            int opti, boolean dumpAll) {
12032        boolean needSep = false;
12033
12034        if (mLruProcesses.size() > 0) {
12035            if (needSep) pw.println();
12036            needSep = true;
12037            pw.println("  OOM levels:");
12038            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12039            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12040            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12041            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12042            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12043            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12044            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12045            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12046            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12047            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12048            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12049            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12050            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12051
12052            if (needSep) pw.println();
12053            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12054                    pw.print(" total, non-act at ");
12055                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12056                    pw.print(", non-svc at ");
12057                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12058                    pw.println("):");
12059            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12060            needSep = true;
12061        }
12062
12063        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12064
12065        pw.println();
12066        pw.println("  mHomeProcess: " + mHomeProcess);
12067        pw.println("  mPreviousProcess: " + mPreviousProcess);
12068        if (mHeavyWeightProcess != null) {
12069            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12070        }
12071
12072        return true;
12073    }
12074
12075    /**
12076     * There are three ways to call this:
12077     *  - no provider specified: dump all the providers
12078     *  - a flattened component name that matched an existing provider was specified as the
12079     *    first arg: dump that one provider
12080     *  - the first arg isn't the flattened component name of an existing provider:
12081     *    dump all providers whose component contains the first arg as a substring
12082     */
12083    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12084            int opti, boolean dumpAll) {
12085        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12086    }
12087
12088    static class ItemMatcher {
12089        ArrayList<ComponentName> components;
12090        ArrayList<String> strings;
12091        ArrayList<Integer> objects;
12092        boolean all;
12093
12094        ItemMatcher() {
12095            all = true;
12096        }
12097
12098        void build(String name) {
12099            ComponentName componentName = ComponentName.unflattenFromString(name);
12100            if (componentName != null) {
12101                if (components == null) {
12102                    components = new ArrayList<ComponentName>();
12103                }
12104                components.add(componentName);
12105                all = false;
12106            } else {
12107                int objectId = 0;
12108                // Not a '/' separated full component name; maybe an object ID?
12109                try {
12110                    objectId = Integer.parseInt(name, 16);
12111                    if (objects == null) {
12112                        objects = new ArrayList<Integer>();
12113                    }
12114                    objects.add(objectId);
12115                    all = false;
12116                } catch (RuntimeException e) {
12117                    // Not an integer; just do string match.
12118                    if (strings == null) {
12119                        strings = new ArrayList<String>();
12120                    }
12121                    strings.add(name);
12122                    all = false;
12123                }
12124            }
12125        }
12126
12127        int build(String[] args, int opti) {
12128            for (; opti<args.length; opti++) {
12129                String name = args[opti];
12130                if ("--".equals(name)) {
12131                    return opti+1;
12132                }
12133                build(name);
12134            }
12135            return opti;
12136        }
12137
12138        boolean match(Object object, ComponentName comp) {
12139            if (all) {
12140                return true;
12141            }
12142            if (components != null) {
12143                for (int i=0; i<components.size(); i++) {
12144                    if (components.get(i).equals(comp)) {
12145                        return true;
12146                    }
12147                }
12148            }
12149            if (objects != null) {
12150                for (int i=0; i<objects.size(); i++) {
12151                    if (System.identityHashCode(object) == objects.get(i)) {
12152                        return true;
12153                    }
12154                }
12155            }
12156            if (strings != null) {
12157                String flat = comp.flattenToString();
12158                for (int i=0; i<strings.size(); i++) {
12159                    if (flat.contains(strings.get(i))) {
12160                        return true;
12161                    }
12162                }
12163            }
12164            return false;
12165        }
12166    }
12167
12168    /**
12169     * There are three things that cmd can be:
12170     *  - a flattened component name that matches an existing activity
12171     *  - the cmd arg isn't the flattened component name of an existing activity:
12172     *    dump all activity whose component contains the cmd as a substring
12173     *  - A hex number of the ActivityRecord object instance.
12174     */
12175    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12176            int opti, boolean dumpAll) {
12177        ArrayList<ActivityRecord> activities;
12178
12179        synchronized (this) {
12180            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12181        }
12182
12183        if (activities.size() <= 0) {
12184            return false;
12185        }
12186
12187        String[] newArgs = new String[args.length - opti];
12188        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12189
12190        TaskRecord lastTask = null;
12191        boolean needSep = false;
12192        for (int i=activities.size()-1; i>=0; i--) {
12193            ActivityRecord r = activities.get(i);
12194            if (needSep) {
12195                pw.println();
12196            }
12197            needSep = true;
12198            synchronized (this) {
12199                if (lastTask != r.task) {
12200                    lastTask = r.task;
12201                    pw.print("TASK "); pw.print(lastTask.affinity);
12202                            pw.print(" id="); pw.println(lastTask.taskId);
12203                    if (dumpAll) {
12204                        lastTask.dump(pw, "  ");
12205                    }
12206                }
12207            }
12208            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12209        }
12210        return true;
12211    }
12212
12213    /**
12214     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12215     * there is a thread associated with the activity.
12216     */
12217    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12218            final ActivityRecord r, String[] args, boolean dumpAll) {
12219        String innerPrefix = prefix + "  ";
12220        synchronized (this) {
12221            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12222                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12223                    pw.print(" pid=");
12224                    if (r.app != null) pw.println(r.app.pid);
12225                    else pw.println("(not running)");
12226            if (dumpAll) {
12227                r.dump(pw, innerPrefix);
12228            }
12229        }
12230        if (r.app != null && r.app.thread != null) {
12231            // flush anything that is already in the PrintWriter since the thread is going
12232            // to write to the file descriptor directly
12233            pw.flush();
12234            try {
12235                TransferPipe tp = new TransferPipe();
12236                try {
12237                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12238                            r.appToken, innerPrefix, args);
12239                    tp.go(fd);
12240                } finally {
12241                    tp.kill();
12242                }
12243            } catch (IOException e) {
12244                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12245            } catch (RemoteException e) {
12246                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12247            }
12248        }
12249    }
12250
12251    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12252            int opti, boolean dumpAll, String dumpPackage) {
12253        boolean needSep = false;
12254        boolean onlyHistory = false;
12255        boolean printedAnything = false;
12256
12257        if ("history".equals(dumpPackage)) {
12258            if (opti < args.length && "-s".equals(args[opti])) {
12259                dumpAll = false;
12260            }
12261            onlyHistory = true;
12262            dumpPackage = null;
12263        }
12264
12265        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12266        if (!onlyHistory && dumpAll) {
12267            if (mRegisteredReceivers.size() > 0) {
12268                boolean printed = false;
12269                Iterator it = mRegisteredReceivers.values().iterator();
12270                while (it.hasNext()) {
12271                    ReceiverList r = (ReceiverList)it.next();
12272                    if (dumpPackage != null && (r.app == null ||
12273                            !dumpPackage.equals(r.app.info.packageName))) {
12274                        continue;
12275                    }
12276                    if (!printed) {
12277                        pw.println("  Registered Receivers:");
12278                        needSep = true;
12279                        printed = true;
12280                        printedAnything = true;
12281                    }
12282                    pw.print("  * "); pw.println(r);
12283                    r.dump(pw, "    ");
12284                }
12285            }
12286
12287            if (mReceiverResolver.dump(pw, needSep ?
12288                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
12289                    "    ", dumpPackage, false)) {
12290                needSep = true;
12291                printedAnything = true;
12292            }
12293        }
12294
12295        for (BroadcastQueue q : mBroadcastQueues) {
12296            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
12297            printedAnything |= needSep;
12298        }
12299
12300        needSep = true;
12301
12302        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
12303            for (int user=0; user<mStickyBroadcasts.size(); user++) {
12304                if (needSep) {
12305                    pw.println();
12306                }
12307                needSep = true;
12308                printedAnything = true;
12309                pw.print("  Sticky broadcasts for user ");
12310                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
12311                StringBuilder sb = new StringBuilder(128);
12312                for (Map.Entry<String, ArrayList<Intent>> ent
12313                        : mStickyBroadcasts.valueAt(user).entrySet()) {
12314                    pw.print("  * Sticky action "); pw.print(ent.getKey());
12315                    if (dumpAll) {
12316                        pw.println(":");
12317                        ArrayList<Intent> intents = ent.getValue();
12318                        final int N = intents.size();
12319                        for (int i=0; i<N; i++) {
12320                            sb.setLength(0);
12321                            sb.append("    Intent: ");
12322                            intents.get(i).toShortString(sb, false, true, false, false);
12323                            pw.println(sb.toString());
12324                            Bundle bundle = intents.get(i).getExtras();
12325                            if (bundle != null) {
12326                                pw.print("      ");
12327                                pw.println(bundle.toString());
12328                            }
12329                        }
12330                    } else {
12331                        pw.println("");
12332                    }
12333                }
12334            }
12335        }
12336
12337        if (!onlyHistory && dumpAll) {
12338            pw.println();
12339            for (BroadcastQueue queue : mBroadcastQueues) {
12340                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
12341                        + queue.mBroadcastsScheduled);
12342            }
12343            pw.println("  mHandler:");
12344            mHandler.dump(new PrintWriterPrinter(pw), "    ");
12345            needSep = true;
12346            printedAnything = true;
12347        }
12348
12349        if (!printedAnything) {
12350            pw.println("  (nothing)");
12351        }
12352    }
12353
12354    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12355            int opti, boolean dumpAll, String dumpPackage) {
12356        boolean needSep;
12357        boolean printedAnything = false;
12358
12359        ItemMatcher matcher = new ItemMatcher();
12360        matcher.build(args, opti);
12361
12362        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
12363
12364        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
12365        printedAnything |= needSep;
12366
12367        if (mLaunchingProviders.size() > 0) {
12368            boolean printed = false;
12369            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
12370                ContentProviderRecord r = mLaunchingProviders.get(i);
12371                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
12372                    continue;
12373                }
12374                if (!printed) {
12375                    if (needSep) pw.println();
12376                    needSep = true;
12377                    pw.println("  Launching content providers:");
12378                    printed = true;
12379                    printedAnything = true;
12380                }
12381                pw.print("  Launching #"); pw.print(i); pw.print(": ");
12382                        pw.println(r);
12383            }
12384        }
12385
12386        if (mGrantedUriPermissions.size() > 0) {
12387            boolean printed = false;
12388            int dumpUid = -2;
12389            if (dumpPackage != null) {
12390                try {
12391                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
12392                } catch (NameNotFoundException e) {
12393                    dumpUid = -1;
12394                }
12395            }
12396            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
12397                int uid = mGrantedUriPermissions.keyAt(i);
12398                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
12399                    continue;
12400                }
12401                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
12402                if (!printed) {
12403                    if (needSep) pw.println();
12404                    needSep = true;
12405                    pw.println("  Granted Uri Permissions:");
12406                    printed = true;
12407                    printedAnything = true;
12408                }
12409                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
12410                for (UriPermission perm : perms.values()) {
12411                    pw.print("    "); pw.println(perm);
12412                    if (dumpAll) {
12413                        perm.dump(pw, "      ");
12414                    }
12415                }
12416            }
12417        }
12418
12419        if (!printedAnything) {
12420            pw.println("  (nothing)");
12421        }
12422    }
12423
12424    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12425            int opti, boolean dumpAll, String dumpPackage) {
12426        boolean printed = false;
12427
12428        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
12429
12430        if (mIntentSenderRecords.size() > 0) {
12431            Iterator<WeakReference<PendingIntentRecord>> it
12432                    = mIntentSenderRecords.values().iterator();
12433            while (it.hasNext()) {
12434                WeakReference<PendingIntentRecord> ref = it.next();
12435                PendingIntentRecord rec = ref != null ? ref.get(): null;
12436                if (dumpPackage != null && (rec == null
12437                        || !dumpPackage.equals(rec.key.packageName))) {
12438                    continue;
12439                }
12440                printed = true;
12441                if (rec != null) {
12442                    pw.print("  * "); pw.println(rec);
12443                    if (dumpAll) {
12444                        rec.dump(pw, "    ");
12445                    }
12446                } else {
12447                    pw.print("  * "); pw.println(ref);
12448                }
12449            }
12450        }
12451
12452        if (!printed) {
12453            pw.println("  (nothing)");
12454        }
12455    }
12456
12457    private static final int dumpProcessList(PrintWriter pw,
12458            ActivityManagerService service, List list,
12459            String prefix, String normalLabel, String persistentLabel,
12460            String dumpPackage) {
12461        int numPers = 0;
12462        final int N = list.size()-1;
12463        for (int i=N; i>=0; i--) {
12464            ProcessRecord r = (ProcessRecord)list.get(i);
12465            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
12466                continue;
12467            }
12468            pw.println(String.format("%s%s #%2d: %s",
12469                    prefix, (r.persistent ? persistentLabel : normalLabel),
12470                    i, r.toString()));
12471            if (r.persistent) {
12472                numPers++;
12473            }
12474        }
12475        return numPers;
12476    }
12477
12478    private static final boolean dumpProcessOomList(PrintWriter pw,
12479            ActivityManagerService service, List<ProcessRecord> origList,
12480            String prefix, String normalLabel, String persistentLabel,
12481            boolean inclDetails, String dumpPackage) {
12482
12483        ArrayList<Pair<ProcessRecord, Integer>> list
12484                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
12485        for (int i=0; i<origList.size(); i++) {
12486            ProcessRecord r = origList.get(i);
12487            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12488                continue;
12489            }
12490            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
12491        }
12492
12493        if (list.size() <= 0) {
12494            return false;
12495        }
12496
12497        Comparator<Pair<ProcessRecord, Integer>> comparator
12498                = new Comparator<Pair<ProcessRecord, Integer>>() {
12499            @Override
12500            public int compare(Pair<ProcessRecord, Integer> object1,
12501                    Pair<ProcessRecord, Integer> object2) {
12502                if (object1.first.setAdj != object2.first.setAdj) {
12503                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
12504                }
12505                if (object1.second.intValue() != object2.second.intValue()) {
12506                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
12507                }
12508                return 0;
12509            }
12510        };
12511
12512        Collections.sort(list, comparator);
12513
12514        final long curRealtime = SystemClock.elapsedRealtime();
12515        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
12516        final long curUptime = SystemClock.uptimeMillis();
12517        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
12518
12519        for (int i=list.size()-1; i>=0; i--) {
12520            ProcessRecord r = list.get(i).first;
12521            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
12522            char schedGroup;
12523            switch (r.setSchedGroup) {
12524                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
12525                    schedGroup = 'B';
12526                    break;
12527                case Process.THREAD_GROUP_DEFAULT:
12528                    schedGroup = 'F';
12529                    break;
12530                default:
12531                    schedGroup = '?';
12532                    break;
12533            }
12534            char foreground;
12535            if (r.foregroundActivities) {
12536                foreground = 'A';
12537            } else if (r.foregroundServices) {
12538                foreground = 'S';
12539            } else {
12540                foreground = ' ';
12541            }
12542            String procState = ProcessList.makeProcStateString(r.curProcState);
12543            pw.print(prefix);
12544            pw.print(r.persistent ? persistentLabel : normalLabel);
12545            pw.print(" #");
12546            int num = (origList.size()-1)-list.get(i).second;
12547            if (num < 10) pw.print(' ');
12548            pw.print(num);
12549            pw.print(": ");
12550            pw.print(oomAdj);
12551            pw.print(' ');
12552            pw.print(schedGroup);
12553            pw.print('/');
12554            pw.print(foreground);
12555            pw.print('/');
12556            pw.print(procState);
12557            pw.print(" trm:");
12558            if (r.trimMemoryLevel < 10) pw.print(' ');
12559            pw.print(r.trimMemoryLevel);
12560            pw.print(' ');
12561            pw.print(r.toShortString());
12562            pw.print(" (");
12563            pw.print(r.adjType);
12564            pw.println(')');
12565            if (r.adjSource != null || r.adjTarget != null) {
12566                pw.print(prefix);
12567                pw.print("    ");
12568                if (r.adjTarget instanceof ComponentName) {
12569                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
12570                } else if (r.adjTarget != null) {
12571                    pw.print(r.adjTarget.toString());
12572                } else {
12573                    pw.print("{null}");
12574                }
12575                pw.print("<=");
12576                if (r.adjSource instanceof ProcessRecord) {
12577                    pw.print("Proc{");
12578                    pw.print(((ProcessRecord)r.adjSource).toShortString());
12579                    pw.println("}");
12580                } else if (r.adjSource != null) {
12581                    pw.println(r.adjSource.toString());
12582                } else {
12583                    pw.println("{null}");
12584                }
12585            }
12586            if (inclDetails) {
12587                pw.print(prefix);
12588                pw.print("    ");
12589                pw.print("oom: max="); pw.print(r.maxAdj);
12590                pw.print(" curRaw="); pw.print(r.curRawAdj);
12591                pw.print(" setRaw="); pw.print(r.setRawAdj);
12592                pw.print(" cur="); pw.print(r.curAdj);
12593                pw.print(" set="); pw.println(r.setAdj);
12594                pw.print(prefix);
12595                pw.print("    ");
12596                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
12597                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
12598                pw.print(" lastPss="); pw.print(r.lastPss);
12599                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
12600                pw.print(prefix);
12601                pw.print("    ");
12602                pw.print("cached="); pw.print(r.cached);
12603                pw.print(" empty="); pw.print(r.empty);
12604                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
12605
12606                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
12607                    if (r.lastWakeTime != 0) {
12608                        long wtime;
12609                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
12610                        synchronized (stats) {
12611                            wtime = stats.getProcessWakeTime(r.info.uid,
12612                                    r.pid, curRealtime);
12613                        }
12614                        long timeUsed = wtime - r.lastWakeTime;
12615                        pw.print(prefix);
12616                        pw.print("    ");
12617                        pw.print("keep awake over ");
12618                        TimeUtils.formatDuration(realtimeSince, pw);
12619                        pw.print(" used ");
12620                        TimeUtils.formatDuration(timeUsed, pw);
12621                        pw.print(" (");
12622                        pw.print((timeUsed*100)/realtimeSince);
12623                        pw.println("%)");
12624                    }
12625                    if (r.lastCpuTime != 0) {
12626                        long timeUsed = r.curCpuTime - r.lastCpuTime;
12627                        pw.print(prefix);
12628                        pw.print("    ");
12629                        pw.print("run cpu over ");
12630                        TimeUtils.formatDuration(uptimeSince, pw);
12631                        pw.print(" used ");
12632                        TimeUtils.formatDuration(timeUsed, pw);
12633                        pw.print(" (");
12634                        pw.print((timeUsed*100)/uptimeSince);
12635                        pw.println("%)");
12636                    }
12637                }
12638            }
12639        }
12640        return true;
12641    }
12642
12643    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
12644        ArrayList<ProcessRecord> procs;
12645        synchronized (this) {
12646            if (args != null && args.length > start
12647                    && args[start].charAt(0) != '-') {
12648                procs = new ArrayList<ProcessRecord>();
12649                int pid = -1;
12650                try {
12651                    pid = Integer.parseInt(args[start]);
12652                } catch (NumberFormatException e) {
12653                }
12654                for (int i=mLruProcesses.size()-1; i>=0; i--) {
12655                    ProcessRecord proc = mLruProcesses.get(i);
12656                    if (proc.pid == pid) {
12657                        procs.add(proc);
12658                    } else if (proc.processName.equals(args[start])) {
12659                        procs.add(proc);
12660                    }
12661                }
12662                if (procs.size() <= 0) {
12663                    return null;
12664                }
12665            } else {
12666                procs = new ArrayList<ProcessRecord>(mLruProcesses);
12667            }
12668        }
12669        return procs;
12670    }
12671
12672    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
12673            PrintWriter pw, String[] args) {
12674        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12675        if (procs == null) {
12676            pw.println("No process found for: " + args[0]);
12677            return;
12678        }
12679
12680        long uptime = SystemClock.uptimeMillis();
12681        long realtime = SystemClock.elapsedRealtime();
12682        pw.println("Applications Graphics Acceleration Info:");
12683        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12684
12685        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12686            ProcessRecord r = procs.get(i);
12687            if (r.thread != null) {
12688                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
12689                pw.flush();
12690                try {
12691                    TransferPipe tp = new TransferPipe();
12692                    try {
12693                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
12694                        tp.go(fd);
12695                    } finally {
12696                        tp.kill();
12697                    }
12698                } catch (IOException e) {
12699                    pw.println("Failure while dumping the app: " + r);
12700                    pw.flush();
12701                } catch (RemoteException e) {
12702                    pw.println("Got a RemoteException while dumping the app " + r);
12703                    pw.flush();
12704                }
12705            }
12706        }
12707    }
12708
12709    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
12710        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
12711        if (procs == null) {
12712            pw.println("No process found for: " + args[0]);
12713            return;
12714        }
12715
12716        pw.println("Applications Database Info:");
12717
12718        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12719            ProcessRecord r = procs.get(i);
12720            if (r.thread != null) {
12721                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
12722                pw.flush();
12723                try {
12724                    TransferPipe tp = new TransferPipe();
12725                    try {
12726                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
12727                        tp.go(fd);
12728                    } finally {
12729                        tp.kill();
12730                    }
12731                } catch (IOException e) {
12732                    pw.println("Failure while dumping the app: " + r);
12733                    pw.flush();
12734                } catch (RemoteException e) {
12735                    pw.println("Got a RemoteException while dumping the app " + r);
12736                    pw.flush();
12737                }
12738            }
12739        }
12740    }
12741
12742    final static class MemItem {
12743        final boolean isProc;
12744        final String label;
12745        final String shortLabel;
12746        final long pss;
12747        final int id;
12748        final boolean hasActivities;
12749        ArrayList<MemItem> subitems;
12750
12751        public MemItem(String _label, String _shortLabel, long _pss, int _id,
12752                boolean _hasActivities) {
12753            isProc = true;
12754            label = _label;
12755            shortLabel = _shortLabel;
12756            pss = _pss;
12757            id = _id;
12758            hasActivities = _hasActivities;
12759        }
12760
12761        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
12762            isProc = false;
12763            label = _label;
12764            shortLabel = _shortLabel;
12765            pss = _pss;
12766            id = _id;
12767            hasActivities = false;
12768        }
12769    }
12770
12771    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
12772            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
12773        if (sort && !isCompact) {
12774            Collections.sort(items, new Comparator<MemItem>() {
12775                @Override
12776                public int compare(MemItem lhs, MemItem rhs) {
12777                    if (lhs.pss < rhs.pss) {
12778                        return 1;
12779                    } else if (lhs.pss > rhs.pss) {
12780                        return -1;
12781                    }
12782                    return 0;
12783                }
12784            });
12785        }
12786
12787        for (int i=0; i<items.size(); i++) {
12788            MemItem mi = items.get(i);
12789            if (!isCompact) {
12790                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
12791            } else if (mi.isProc) {
12792                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
12793                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
12794                pw.println(mi.hasActivities ? ",a" : ",e");
12795            } else {
12796                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
12797                pw.println(mi.pss);
12798            }
12799            if (mi.subitems != null) {
12800                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
12801                        true, isCompact);
12802            }
12803        }
12804    }
12805
12806    // These are in KB.
12807    static final long[] DUMP_MEM_BUCKETS = new long[] {
12808        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
12809        120*1024, 160*1024, 200*1024,
12810        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
12811        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
12812    };
12813
12814    static final void appendMemBucket(StringBuilder out, long memKB, String label,
12815            boolean stackLike) {
12816        int start = label.lastIndexOf('.');
12817        if (start >= 0) start++;
12818        else start = 0;
12819        int end = label.length();
12820        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
12821            if (DUMP_MEM_BUCKETS[i] >= memKB) {
12822                long bucket = DUMP_MEM_BUCKETS[i]/1024;
12823                out.append(bucket);
12824                out.append(stackLike ? "MB." : "MB ");
12825                out.append(label, start, end);
12826                return;
12827            }
12828        }
12829        out.append(memKB/1024);
12830        out.append(stackLike ? "MB." : "MB ");
12831        out.append(label, start, end);
12832    }
12833
12834    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
12835            ProcessList.NATIVE_ADJ,
12836            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
12837            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
12838            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
12839            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
12840            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
12841    };
12842    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
12843            "Native",
12844            "System", "Persistent", "Foreground",
12845            "Visible", "Perceptible",
12846            "Heavy Weight", "Backup",
12847            "A Services", "Home",
12848            "Previous", "B Services", "Cached"
12849    };
12850    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
12851            "native",
12852            "sys", "pers", "fore",
12853            "vis", "percept",
12854            "heavy", "backup",
12855            "servicea", "home",
12856            "prev", "serviceb", "cached"
12857    };
12858
12859    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
12860            long realtime, boolean isCheckinRequest, boolean isCompact) {
12861        if (isCheckinRequest || isCompact) {
12862            // short checkin version
12863            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
12864        } else {
12865            pw.println("Applications Memory Usage (kB):");
12866            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
12867        }
12868    }
12869
12870    final void dumpApplicationMemoryUsage(FileDescriptor fd,
12871            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
12872        boolean dumpDetails = false;
12873        boolean dumpFullDetails = false;
12874        boolean dumpDalvik = false;
12875        boolean oomOnly = false;
12876        boolean isCompact = false;
12877        boolean localOnly = false;
12878
12879        int opti = 0;
12880        while (opti < args.length) {
12881            String opt = args[opti];
12882            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12883                break;
12884            }
12885            opti++;
12886            if ("-a".equals(opt)) {
12887                dumpDetails = true;
12888                dumpFullDetails = true;
12889                dumpDalvik = true;
12890            } else if ("-d".equals(opt)) {
12891                dumpDalvik = true;
12892            } else if ("-c".equals(opt)) {
12893                isCompact = true;
12894            } else if ("--oom".equals(opt)) {
12895                oomOnly = true;
12896            } else if ("--local".equals(opt)) {
12897                localOnly = true;
12898            } else if ("-h".equals(opt)) {
12899                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
12900                pw.println("  -a: include all available information for each process.");
12901                pw.println("  -d: include dalvik details when dumping process details.");
12902                pw.println("  -c: dump in a compact machine-parseable representation.");
12903                pw.println("  --oom: only show processes organized by oom adj.");
12904                pw.println("  --local: only collect details locally, don't call process.");
12905                pw.println("If [process] is specified it can be the name or ");
12906                pw.println("pid of a specific process to dump.");
12907                return;
12908            } else {
12909                pw.println("Unknown argument: " + opt + "; use -h for help");
12910            }
12911        }
12912
12913        final boolean isCheckinRequest = scanArgs(args, "--checkin");
12914        long uptime = SystemClock.uptimeMillis();
12915        long realtime = SystemClock.elapsedRealtime();
12916        final long[] tmpLong = new long[1];
12917
12918        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
12919        if (procs == null) {
12920            // No Java processes.  Maybe they want to print a native process.
12921            if (args != null && args.length > opti
12922                    && args[opti].charAt(0) != '-') {
12923                ArrayList<ProcessCpuTracker.Stats> nativeProcs
12924                        = new ArrayList<ProcessCpuTracker.Stats>();
12925                updateCpuStatsNow();
12926                int findPid = -1;
12927                try {
12928                    findPid = Integer.parseInt(args[opti]);
12929                } catch (NumberFormatException e) {
12930                }
12931                synchronized (mProcessCpuThread) {
12932                    final int N = mProcessCpuTracker.countStats();
12933                    for (int i=0; i<N; i++) {
12934                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
12935                        if (st.pid == findPid || (st.baseName != null
12936                                && st.baseName.equals(args[opti]))) {
12937                            nativeProcs.add(st);
12938                        }
12939                    }
12940                }
12941                if (nativeProcs.size() > 0) {
12942                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
12943                            isCompact);
12944                    Debug.MemoryInfo mi = null;
12945                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
12946                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
12947                        final int pid = r.pid;
12948                        if (!isCheckinRequest && dumpDetails) {
12949                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
12950                        }
12951                        if (mi == null) {
12952                            mi = new Debug.MemoryInfo();
12953                        }
12954                        if (dumpDetails || (!brief && !oomOnly)) {
12955                            Debug.getMemoryInfo(pid, mi);
12956                        } else {
12957                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
12958                            mi.dalvikPrivateDirty = (int)tmpLong[0];
12959                        }
12960                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
12961                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
12962                        if (isCheckinRequest) {
12963                            pw.println();
12964                        }
12965                    }
12966                    return;
12967                }
12968            }
12969            pw.println("No process found for: " + args[opti]);
12970            return;
12971        }
12972
12973        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
12974            dumpDetails = true;
12975        }
12976
12977        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
12978
12979        String[] innerArgs = new String[args.length-opti];
12980        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
12981
12982        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
12983        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
12984        long nativePss=0, dalvikPss=0, otherPss=0;
12985        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
12986
12987        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
12988        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
12989                new ArrayList[DUMP_MEM_OOM_LABEL.length];
12990
12991        long totalPss = 0;
12992        long cachedPss = 0;
12993
12994        Debug.MemoryInfo mi = null;
12995        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
12996            final ProcessRecord r = procs.get(i);
12997            final IApplicationThread thread;
12998            final int pid;
12999            final int oomAdj;
13000            final boolean hasActivities;
13001            synchronized (this) {
13002                thread = r.thread;
13003                pid = r.pid;
13004                oomAdj = r.getSetAdjWithServices();
13005                hasActivities = r.activities.size() > 0;
13006            }
13007            if (thread != null) {
13008                if (!isCheckinRequest && dumpDetails) {
13009                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13010                }
13011                if (mi == null) {
13012                    mi = new Debug.MemoryInfo();
13013                }
13014                if (dumpDetails || (!brief && !oomOnly)) {
13015                    Debug.getMemoryInfo(pid, mi);
13016                } else {
13017                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13018                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13019                }
13020                if (dumpDetails) {
13021                    if (localOnly) {
13022                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13023                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13024                        if (isCheckinRequest) {
13025                            pw.println();
13026                        }
13027                    } else {
13028                        try {
13029                            pw.flush();
13030                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13031                                    dumpDalvik, innerArgs);
13032                        } catch (RemoteException e) {
13033                            if (!isCheckinRequest) {
13034                                pw.println("Got RemoteException!");
13035                                pw.flush();
13036                            }
13037                        }
13038                    }
13039                }
13040
13041                final long myTotalPss = mi.getTotalPss();
13042                final long myTotalUss = mi.getTotalUss();
13043
13044                synchronized (this) {
13045                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13046                        // Record this for posterity if the process has been stable.
13047                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13048                    }
13049                }
13050
13051                if (!isCheckinRequest && mi != null) {
13052                    totalPss += myTotalPss;
13053                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13054                            (hasActivities ? " / activities)" : ")"),
13055                            r.processName, myTotalPss, pid, hasActivities);
13056                    procMems.add(pssItem);
13057                    procMemsMap.put(pid, pssItem);
13058
13059                    nativePss += mi.nativePss;
13060                    dalvikPss += mi.dalvikPss;
13061                    otherPss += mi.otherPss;
13062                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13063                        long mem = mi.getOtherPss(j);
13064                        miscPss[j] += mem;
13065                        otherPss -= mem;
13066                    }
13067
13068                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13069                        cachedPss += myTotalPss;
13070                    }
13071
13072                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13073                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13074                                || oomIndex == (oomPss.length-1)) {
13075                            oomPss[oomIndex] += myTotalPss;
13076                            if (oomProcs[oomIndex] == null) {
13077                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13078                            }
13079                            oomProcs[oomIndex].add(pssItem);
13080                            break;
13081                        }
13082                    }
13083                }
13084            }
13085        }
13086
13087        long nativeProcTotalPss = 0;
13088
13089        if (!isCheckinRequest && procs.size() > 1) {
13090            // If we are showing aggregations, also look for native processes to
13091            // include so that our aggregations are more accurate.
13092            updateCpuStatsNow();
13093            synchronized (mProcessCpuThread) {
13094                final int N = mProcessCpuTracker.countStats();
13095                for (int i=0; i<N; i++) {
13096                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13097                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13098                        if (mi == null) {
13099                            mi = new Debug.MemoryInfo();
13100                        }
13101                        if (!brief && !oomOnly) {
13102                            Debug.getMemoryInfo(st.pid, mi);
13103                        } else {
13104                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13105                            mi.nativePrivateDirty = (int)tmpLong[0];
13106                        }
13107
13108                        final long myTotalPss = mi.getTotalPss();
13109                        totalPss += myTotalPss;
13110                        nativeProcTotalPss += myTotalPss;
13111
13112                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13113                                st.name, myTotalPss, st.pid, false);
13114                        procMems.add(pssItem);
13115
13116                        nativePss += mi.nativePss;
13117                        dalvikPss += mi.dalvikPss;
13118                        otherPss += mi.otherPss;
13119                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13120                            long mem = mi.getOtherPss(j);
13121                            miscPss[j] += mem;
13122                            otherPss -= mem;
13123                        }
13124                        oomPss[0] += myTotalPss;
13125                        if (oomProcs[0] == null) {
13126                            oomProcs[0] = new ArrayList<MemItem>();
13127                        }
13128                        oomProcs[0].add(pssItem);
13129                    }
13130                }
13131            }
13132
13133            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13134
13135            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13136            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13137            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13138            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13139                String label = Debug.MemoryInfo.getOtherLabel(j);
13140                catMems.add(new MemItem(label, label, miscPss[j], j));
13141            }
13142
13143            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13144            for (int j=0; j<oomPss.length; j++) {
13145                if (oomPss[j] != 0) {
13146                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13147                            : DUMP_MEM_OOM_LABEL[j];
13148                    MemItem item = new MemItem(label, label, oomPss[j],
13149                            DUMP_MEM_OOM_ADJ[j]);
13150                    item.subitems = oomProcs[j];
13151                    oomMems.add(item);
13152                }
13153            }
13154
13155            if (!brief && !oomOnly && !isCompact) {
13156                pw.println();
13157                pw.println("Total PSS by process:");
13158                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13159                pw.println();
13160            }
13161            if (!isCompact) {
13162                pw.println("Total PSS by OOM adjustment:");
13163            }
13164            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13165            if (!brief && !oomOnly) {
13166                PrintWriter out = categoryPw != null ? categoryPw : pw;
13167                if (!isCompact) {
13168                    out.println();
13169                    out.println("Total PSS by category:");
13170                }
13171                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13172            }
13173            if (!isCompact) {
13174                pw.println();
13175            }
13176            MemInfoReader memInfo = new MemInfoReader();
13177            memInfo.readMemInfo();
13178            if (nativeProcTotalPss > 0) {
13179                synchronized (this) {
13180                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13181                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13182                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13183                            nativeProcTotalPss);
13184                }
13185            }
13186            if (!brief) {
13187                if (!isCompact) {
13188                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13189                    pw.print(" kB (status ");
13190                    switch (mLastMemoryLevel) {
13191                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13192                            pw.println("normal)");
13193                            break;
13194                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13195                            pw.println("moderate)");
13196                            break;
13197                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13198                            pw.println("low)");
13199                            break;
13200                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13201                            pw.println("critical)");
13202                            break;
13203                        default:
13204                            pw.print(mLastMemoryLevel);
13205                            pw.println(")");
13206                            break;
13207                    }
13208                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13209                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13210                            pw.print(cachedPss); pw.print(" cached pss + ");
13211                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13212                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13213                } else {
13214                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13215                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13216                            + memInfo.getFreeSizeKb()); pw.print(",");
13217                    pw.println(totalPss - cachedPss);
13218                }
13219            }
13220            if (!isCompact) {
13221                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13222                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13223                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13224                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13225                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13226                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13227                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13228                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13229                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13230                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13231                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13232            }
13233            if (!brief) {
13234                if (memInfo.getZramTotalSizeKb() != 0) {
13235                    if (!isCompact) {
13236                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13237                                pw.print(" kB physical used for ");
13238                                pw.print(memInfo.getSwapTotalSizeKb()
13239                                        - memInfo.getSwapFreeSizeKb());
13240                                pw.print(" kB in swap (");
13241                                pw.print(memInfo.getSwapTotalSizeKb());
13242                                pw.println(" kB total swap)");
13243                    } else {
13244                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13245                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13246                                pw.println(memInfo.getSwapFreeSizeKb());
13247                    }
13248                }
13249                final int[] SINGLE_LONG_FORMAT = new int[] {
13250                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13251                };
13252                long[] longOut = new long[1];
13253                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13254                        SINGLE_LONG_FORMAT, null, longOut, null);
13255                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13256                longOut[0] = 0;
13257                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13258                        SINGLE_LONG_FORMAT, null, longOut, null);
13259                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13260                longOut[0] = 0;
13261                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13262                        SINGLE_LONG_FORMAT, null, longOut, null);
13263                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13264                longOut[0] = 0;
13265                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13266                        SINGLE_LONG_FORMAT, null, longOut, null);
13267                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13268                if (!isCompact) {
13269                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13270                        pw.print("      KSM: "); pw.print(sharing);
13271                                pw.print(" kB saved from shared ");
13272                                pw.print(shared); pw.println(" kB");
13273                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
13274                                pw.print(voltile); pw.println(" kB volatile");
13275                    }
13276                    pw.print("   Tuning: ");
13277                    pw.print(ActivityManager.staticGetMemoryClass());
13278                    pw.print(" (large ");
13279                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13280                    pw.print("), oom ");
13281                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13282                    pw.print(" kB");
13283                    pw.print(", restore limit ");
13284                    pw.print(mProcessList.getCachedRestoreThresholdKb());
13285                    pw.print(" kB");
13286                    if (ActivityManager.isLowRamDeviceStatic()) {
13287                        pw.print(" (low-ram)");
13288                    }
13289                    if (ActivityManager.isHighEndGfx()) {
13290                        pw.print(" (high-end-gfx)");
13291                    }
13292                    pw.println();
13293                } else {
13294                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
13295                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
13296                    pw.println(voltile);
13297                    pw.print("tuning,");
13298                    pw.print(ActivityManager.staticGetMemoryClass());
13299                    pw.print(',');
13300                    pw.print(ActivityManager.staticGetLargeMemoryClass());
13301                    pw.print(',');
13302                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
13303                    if (ActivityManager.isLowRamDeviceStatic()) {
13304                        pw.print(",low-ram");
13305                    }
13306                    if (ActivityManager.isHighEndGfx()) {
13307                        pw.print(",high-end-gfx");
13308                    }
13309                    pw.println();
13310                }
13311            }
13312        }
13313    }
13314
13315    /**
13316     * Searches array of arguments for the specified string
13317     * @param args array of argument strings
13318     * @param value value to search for
13319     * @return true if the value is contained in the array
13320     */
13321    private static boolean scanArgs(String[] args, String value) {
13322        if (args != null) {
13323            for (String arg : args) {
13324                if (value.equals(arg)) {
13325                    return true;
13326                }
13327            }
13328        }
13329        return false;
13330    }
13331
13332    private final boolean removeDyingProviderLocked(ProcessRecord proc,
13333            ContentProviderRecord cpr, boolean always) {
13334        final boolean inLaunching = mLaunchingProviders.contains(cpr);
13335
13336        if (!inLaunching || always) {
13337            synchronized (cpr) {
13338                cpr.launchingApp = null;
13339                cpr.notifyAll();
13340            }
13341            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
13342            String names[] = cpr.info.authority.split(";");
13343            for (int j = 0; j < names.length; j++) {
13344                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
13345            }
13346        }
13347
13348        for (int i=0; i<cpr.connections.size(); i++) {
13349            ContentProviderConnection conn = cpr.connections.get(i);
13350            if (conn.waiting) {
13351                // If this connection is waiting for the provider, then we don't
13352                // need to mess with its process unless we are always removing
13353                // or for some reason the provider is not currently launching.
13354                if (inLaunching && !always) {
13355                    continue;
13356                }
13357            }
13358            ProcessRecord capp = conn.client;
13359            conn.dead = true;
13360            if (conn.stableCount > 0) {
13361                if (!capp.persistent && capp.thread != null
13362                        && capp.pid != 0
13363                        && capp.pid != MY_PID) {
13364                    killUnneededProcessLocked(capp, "depends on provider "
13365                            + cpr.name.flattenToShortString()
13366                            + " in dying proc " + (proc != null ? proc.processName : "??"));
13367                }
13368            } else if (capp.thread != null && conn.provider.provider != null) {
13369                try {
13370                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
13371                } catch (RemoteException e) {
13372                }
13373                // In the protocol here, we don't expect the client to correctly
13374                // clean up this connection, we'll just remove it.
13375                cpr.connections.remove(i);
13376                conn.client.conProviders.remove(conn);
13377            }
13378        }
13379
13380        if (inLaunching && always) {
13381            mLaunchingProviders.remove(cpr);
13382        }
13383        return inLaunching;
13384    }
13385
13386    /**
13387     * Main code for cleaning up a process when it has gone away.  This is
13388     * called both as a result of the process dying, or directly when stopping
13389     * a process when running in single process mode.
13390     */
13391    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
13392            boolean restarting, boolean allowRestart, int index) {
13393        if (index >= 0) {
13394            removeLruProcessLocked(app);
13395            ProcessList.remove(app.pid);
13396        }
13397
13398        mProcessesToGc.remove(app);
13399        mPendingPssProcesses.remove(app);
13400
13401        // Dismiss any open dialogs.
13402        if (app.crashDialog != null && !app.forceCrashReport) {
13403            app.crashDialog.dismiss();
13404            app.crashDialog = null;
13405        }
13406        if (app.anrDialog != null) {
13407            app.anrDialog.dismiss();
13408            app.anrDialog = null;
13409        }
13410        if (app.waitDialog != null) {
13411            app.waitDialog.dismiss();
13412            app.waitDialog = null;
13413        }
13414
13415        app.crashing = false;
13416        app.notResponding = false;
13417
13418        app.resetPackageList(mProcessStats);
13419        app.unlinkDeathRecipient();
13420        app.makeInactive(mProcessStats);
13421        app.waitingToKill = null;
13422        app.forcingToForeground = null;
13423        updateProcessForegroundLocked(app, false, false);
13424        app.foregroundActivities = false;
13425        app.hasShownUi = false;
13426        app.treatLikeActivity = false;
13427        app.hasAboveClient = false;
13428        app.hasClientActivities = false;
13429
13430        mServices.killServicesLocked(app, allowRestart);
13431
13432        boolean restart = false;
13433
13434        // Remove published content providers.
13435        for (int i=app.pubProviders.size()-1; i>=0; i--) {
13436            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
13437            final boolean always = app.bad || !allowRestart;
13438            if (removeDyingProviderLocked(app, cpr, always) || always) {
13439                // We left the provider in the launching list, need to
13440                // restart it.
13441                restart = true;
13442            }
13443
13444            cpr.provider = null;
13445            cpr.proc = null;
13446        }
13447        app.pubProviders.clear();
13448
13449        // Take care of any launching providers waiting for this process.
13450        if (checkAppInLaunchingProvidersLocked(app, false)) {
13451            restart = true;
13452        }
13453
13454        // Unregister from connected content providers.
13455        if (!app.conProviders.isEmpty()) {
13456            for (int i=0; i<app.conProviders.size(); i++) {
13457                ContentProviderConnection conn = app.conProviders.get(i);
13458                conn.provider.connections.remove(conn);
13459            }
13460            app.conProviders.clear();
13461        }
13462
13463        // At this point there may be remaining entries in mLaunchingProviders
13464        // where we were the only one waiting, so they are no longer of use.
13465        // Look for these and clean up if found.
13466        // XXX Commented out for now.  Trying to figure out a way to reproduce
13467        // the actual situation to identify what is actually going on.
13468        if (false) {
13469            for (int i=0; i<mLaunchingProviders.size(); i++) {
13470                ContentProviderRecord cpr = (ContentProviderRecord)
13471                        mLaunchingProviders.get(i);
13472                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
13473                    synchronized (cpr) {
13474                        cpr.launchingApp = null;
13475                        cpr.notifyAll();
13476                    }
13477                }
13478            }
13479        }
13480
13481        skipCurrentReceiverLocked(app);
13482
13483        // Unregister any receivers.
13484        for (int i=app.receivers.size()-1; i>=0; i--) {
13485            removeReceiverLocked(app.receivers.valueAt(i));
13486        }
13487        app.receivers.clear();
13488
13489        // If the app is undergoing backup, tell the backup manager about it
13490        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
13491            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
13492                    + mBackupTarget.appInfo + " died during backup");
13493            try {
13494                IBackupManager bm = IBackupManager.Stub.asInterface(
13495                        ServiceManager.getService(Context.BACKUP_SERVICE));
13496                bm.agentDisconnected(app.info.packageName);
13497            } catch (RemoteException e) {
13498                // can't happen; backup manager is local
13499            }
13500        }
13501
13502        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
13503            ProcessChangeItem item = mPendingProcessChanges.get(i);
13504            if (item.pid == app.pid) {
13505                mPendingProcessChanges.remove(i);
13506                mAvailProcessChanges.add(item);
13507            }
13508        }
13509        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
13510
13511        // If the caller is restarting this app, then leave it in its
13512        // current lists and let the caller take care of it.
13513        if (restarting) {
13514            return;
13515        }
13516
13517        if (!app.persistent || app.isolated) {
13518            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
13519                    "Removing non-persistent process during cleanup: " + app);
13520            mProcessNames.remove(app.processName, app.uid);
13521            mIsolatedProcesses.remove(app.uid);
13522            if (mHeavyWeightProcess == app) {
13523                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
13524                        mHeavyWeightProcess.userId, 0));
13525                mHeavyWeightProcess = null;
13526            }
13527        } else if (!app.removed) {
13528            // This app is persistent, so we need to keep its record around.
13529            // If it is not already on the pending app list, add it there
13530            // and start a new process for it.
13531            if (mPersistentStartingProcesses.indexOf(app) < 0) {
13532                mPersistentStartingProcesses.add(app);
13533                restart = true;
13534            }
13535        }
13536        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
13537                "Clean-up removing on hold: " + app);
13538        mProcessesOnHold.remove(app);
13539
13540        if (app == mHomeProcess) {
13541            mHomeProcess = null;
13542        }
13543        if (app == mPreviousProcess) {
13544            mPreviousProcess = null;
13545        }
13546
13547        if (restart && !app.isolated) {
13548            // We have components that still need to be running in the
13549            // process, so re-launch it.
13550            mProcessNames.put(app.processName, app.uid, app);
13551            startProcessLocked(app, "restart", app.processName, null /* ABI override */,
13552                    null /* entryPoint */, null /* entryPointArgs */);
13553        } else if (app.pid > 0 && app.pid != MY_PID) {
13554            // Goodbye!
13555            boolean removed;
13556            synchronized (mPidsSelfLocked) {
13557                mPidsSelfLocked.remove(app.pid);
13558                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
13559            }
13560            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
13561            if (app.isolated) {
13562                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
13563            }
13564            app.setPid(0);
13565        }
13566    }
13567
13568    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
13569        // Look through the content providers we are waiting to have launched,
13570        // and if any run in this process then either schedule a restart of
13571        // the process or kill the client waiting for it if this process has
13572        // gone bad.
13573        int NL = mLaunchingProviders.size();
13574        boolean restart = false;
13575        for (int i=0; i<NL; i++) {
13576            ContentProviderRecord cpr = mLaunchingProviders.get(i);
13577            if (cpr.launchingApp == app) {
13578                if (!alwaysBad && !app.bad) {
13579                    restart = true;
13580                } else {
13581                    removeDyingProviderLocked(app, cpr, true);
13582                    // cpr should have been removed from mLaunchingProviders
13583                    NL = mLaunchingProviders.size();
13584                    i--;
13585                }
13586            }
13587        }
13588        return restart;
13589    }
13590
13591    // =========================================================
13592    // SERVICES
13593    // =========================================================
13594
13595    @Override
13596    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
13597            int flags) {
13598        enforceNotIsolatedCaller("getServices");
13599        synchronized (this) {
13600            return mServices.getRunningServiceInfoLocked(maxNum, flags);
13601        }
13602    }
13603
13604    @Override
13605    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
13606        enforceNotIsolatedCaller("getRunningServiceControlPanel");
13607        synchronized (this) {
13608            return mServices.getRunningServiceControlPanelLocked(name);
13609        }
13610    }
13611
13612    @Override
13613    public ComponentName startService(IApplicationThread caller, Intent service,
13614            String resolvedType, int userId) {
13615        enforceNotIsolatedCaller("startService");
13616        // Refuse possible leaked file descriptors
13617        if (service != null && service.hasFileDescriptors() == true) {
13618            throw new IllegalArgumentException("File descriptors passed in Intent");
13619        }
13620
13621        if (DEBUG_SERVICE)
13622            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
13623        synchronized(this) {
13624            final int callingPid = Binder.getCallingPid();
13625            final int callingUid = Binder.getCallingUid();
13626            final long origId = Binder.clearCallingIdentity();
13627            ComponentName res = mServices.startServiceLocked(caller, service,
13628                    resolvedType, callingPid, callingUid, userId);
13629            Binder.restoreCallingIdentity(origId);
13630            return res;
13631        }
13632    }
13633
13634    ComponentName startServiceInPackage(int uid,
13635            Intent service, String resolvedType, int userId) {
13636        synchronized(this) {
13637            if (DEBUG_SERVICE)
13638                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
13639            final long origId = Binder.clearCallingIdentity();
13640            ComponentName res = mServices.startServiceLocked(null, service,
13641                    resolvedType, -1, uid, userId);
13642            Binder.restoreCallingIdentity(origId);
13643            return res;
13644        }
13645    }
13646
13647    @Override
13648    public int stopService(IApplicationThread caller, Intent service,
13649            String resolvedType, int userId) {
13650        enforceNotIsolatedCaller("stopService");
13651        // Refuse possible leaked file descriptors
13652        if (service != null && service.hasFileDescriptors() == true) {
13653            throw new IllegalArgumentException("File descriptors passed in Intent");
13654        }
13655
13656        synchronized(this) {
13657            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
13658        }
13659    }
13660
13661    @Override
13662    public IBinder peekService(Intent service, String resolvedType) {
13663        enforceNotIsolatedCaller("peekService");
13664        // Refuse possible leaked file descriptors
13665        if (service != null && service.hasFileDescriptors() == true) {
13666            throw new IllegalArgumentException("File descriptors passed in Intent");
13667        }
13668        synchronized(this) {
13669            return mServices.peekServiceLocked(service, resolvedType);
13670        }
13671    }
13672
13673    @Override
13674    public boolean stopServiceToken(ComponentName className, IBinder token,
13675            int startId) {
13676        synchronized(this) {
13677            return mServices.stopServiceTokenLocked(className, token, startId);
13678        }
13679    }
13680
13681    @Override
13682    public void setServiceForeground(ComponentName className, IBinder token,
13683            int id, Notification notification, boolean removeNotification) {
13684        synchronized(this) {
13685            mServices.setServiceForegroundLocked(className, token, id, notification,
13686                    removeNotification);
13687        }
13688    }
13689
13690    @Override
13691    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13692            boolean requireFull, String name, String callerPackage) {
13693        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
13694                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
13695    }
13696
13697    int unsafeConvertIncomingUser(int userId) {
13698        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
13699                ? mCurrentUserId : userId;
13700    }
13701
13702    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
13703            int allowMode, String name, String callerPackage) {
13704        final int callingUserId = UserHandle.getUserId(callingUid);
13705        if (callingUserId == userId) {
13706            return userId;
13707        }
13708
13709        // Note that we may be accessing mCurrentUserId outside of a lock...
13710        // shouldn't be a big deal, if this is being called outside
13711        // of a locked context there is intrinsically a race with
13712        // the value the caller will receive and someone else changing it.
13713        // We assume that USER_CURRENT_OR_SELF will use the current user; later
13714        // we will switch to the calling user if access to the current user fails.
13715        int targetUserId = unsafeConvertIncomingUser(userId);
13716
13717        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
13718            final boolean allow;
13719            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
13720                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
13721                // If the caller has this permission, they always pass go.  And collect $200.
13722                allow = true;
13723            } else if (allowMode == ALLOW_FULL_ONLY) {
13724                // We require full access, sucks to be you.
13725                allow = false;
13726            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
13727                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
13728                // If the caller does not have either permission, they are always doomed.
13729                allow = false;
13730            } else if (allowMode == ALLOW_NON_FULL) {
13731                // We are blanket allowing non-full access, you lucky caller!
13732                allow = true;
13733            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
13734                // We may or may not allow this depending on whether the two users are
13735                // in the same profile.
13736                synchronized (mUserProfileGroupIdsSelfLocked) {
13737                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
13738                            UserInfo.NO_PROFILE_GROUP_ID);
13739                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
13740                            UserInfo.NO_PROFILE_GROUP_ID);
13741                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
13742                            && callingProfile == targetProfile;
13743                }
13744            } else {
13745                throw new IllegalArgumentException("Unknown mode: " + allowMode);
13746            }
13747            if (!allow) {
13748                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
13749                    // In this case, they would like to just execute as their
13750                    // owner user instead of failing.
13751                    targetUserId = callingUserId;
13752                } else {
13753                    StringBuilder builder = new StringBuilder(128);
13754                    builder.append("Permission Denial: ");
13755                    builder.append(name);
13756                    if (callerPackage != null) {
13757                        builder.append(" from ");
13758                        builder.append(callerPackage);
13759                    }
13760                    builder.append(" asks to run as user ");
13761                    builder.append(userId);
13762                    builder.append(" but is calling from user ");
13763                    builder.append(UserHandle.getUserId(callingUid));
13764                    builder.append("; this requires ");
13765                    builder.append(INTERACT_ACROSS_USERS_FULL);
13766                    if (allowMode != ALLOW_FULL_ONLY) {
13767                        builder.append(" or ");
13768                        builder.append(INTERACT_ACROSS_USERS);
13769                    }
13770                    String msg = builder.toString();
13771                    Slog.w(TAG, msg);
13772                    throw new SecurityException(msg);
13773                }
13774            }
13775        }
13776        if (!allowAll && targetUserId < 0) {
13777            throw new IllegalArgumentException(
13778                    "Call does not support special user #" + targetUserId);
13779        }
13780        return targetUserId;
13781    }
13782
13783    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
13784            String className, int flags) {
13785        boolean result = false;
13786        // For apps that don't have pre-defined UIDs, check for permission
13787        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
13788            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
13789                if (ActivityManager.checkUidPermission(
13790                        INTERACT_ACROSS_USERS,
13791                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
13792                    ComponentName comp = new ComponentName(aInfo.packageName, className);
13793                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
13794                            + " requests FLAG_SINGLE_USER, but app does not hold "
13795                            + INTERACT_ACROSS_USERS;
13796                    Slog.w(TAG, msg);
13797                    throw new SecurityException(msg);
13798                }
13799                // Permission passed
13800                result = true;
13801            }
13802        } else if ("system".equals(componentProcessName)) {
13803            result = true;
13804        } else {
13805            // App with pre-defined UID, check if it's a persistent app
13806            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
13807        }
13808        if (DEBUG_MU) {
13809            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
13810                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
13811        }
13812        return result;
13813    }
13814
13815    /**
13816     * Checks to see if the caller is in the same app as the singleton
13817     * component, or the component is in a special app. It allows special apps
13818     * to export singleton components but prevents exporting singleton
13819     * components for regular apps.
13820     */
13821    boolean isValidSingletonCall(int callingUid, int componentUid) {
13822        int componentAppId = UserHandle.getAppId(componentUid);
13823        return UserHandle.isSameApp(callingUid, componentUid)
13824                || componentAppId == Process.SYSTEM_UID
13825                || componentAppId == Process.PHONE_UID
13826                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
13827                        == PackageManager.PERMISSION_GRANTED;
13828    }
13829
13830    public int bindService(IApplicationThread caller, IBinder token,
13831            Intent service, String resolvedType,
13832            IServiceConnection connection, int flags, int userId) {
13833        enforceNotIsolatedCaller("bindService");
13834        // Refuse possible leaked file descriptors
13835        if (service != null && service.hasFileDescriptors() == true) {
13836            throw new IllegalArgumentException("File descriptors passed in Intent");
13837        }
13838
13839        synchronized(this) {
13840            return mServices.bindServiceLocked(caller, token, service, resolvedType,
13841                    connection, flags, userId);
13842        }
13843    }
13844
13845    public boolean unbindService(IServiceConnection connection) {
13846        synchronized (this) {
13847            return mServices.unbindServiceLocked(connection);
13848        }
13849    }
13850
13851    public void publishService(IBinder token, Intent intent, IBinder service) {
13852        // Refuse possible leaked file descriptors
13853        if (intent != null && intent.hasFileDescriptors() == true) {
13854            throw new IllegalArgumentException("File descriptors passed in Intent");
13855        }
13856
13857        synchronized(this) {
13858            if (!(token instanceof ServiceRecord)) {
13859                throw new IllegalArgumentException("Invalid service token");
13860            }
13861            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
13862        }
13863    }
13864
13865    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
13866        // Refuse possible leaked file descriptors
13867        if (intent != null && intent.hasFileDescriptors() == true) {
13868            throw new IllegalArgumentException("File descriptors passed in Intent");
13869        }
13870
13871        synchronized(this) {
13872            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
13873        }
13874    }
13875
13876    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
13877        synchronized(this) {
13878            if (!(token instanceof ServiceRecord)) {
13879                throw new IllegalArgumentException("Invalid service token");
13880            }
13881            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
13882        }
13883    }
13884
13885    // =========================================================
13886    // BACKUP AND RESTORE
13887    // =========================================================
13888
13889    // Cause the target app to be launched if necessary and its backup agent
13890    // instantiated.  The backup agent will invoke backupAgentCreated() on the
13891    // activity manager to announce its creation.
13892    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
13893        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
13894        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
13895
13896        synchronized(this) {
13897            // !!! TODO: currently no check here that we're already bound
13898            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
13899            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13900            synchronized (stats) {
13901                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
13902            }
13903
13904            // Backup agent is now in use, its package can't be stopped.
13905            try {
13906                AppGlobals.getPackageManager().setPackageStoppedState(
13907                        app.packageName, false, UserHandle.getUserId(app.uid));
13908            } catch (RemoteException e) {
13909            } catch (IllegalArgumentException e) {
13910                Slog.w(TAG, "Failed trying to unstop package "
13911                        + app.packageName + ": " + e);
13912            }
13913
13914            BackupRecord r = new BackupRecord(ss, app, backupMode);
13915            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
13916                    ? new ComponentName(app.packageName, app.backupAgentName)
13917                    : new ComponentName("android", "FullBackupAgent");
13918            // startProcessLocked() returns existing proc's record if it's already running
13919            ProcessRecord proc = startProcessLocked(app.processName, app,
13920                    false, 0, "backup", hostingName, false, false, false);
13921            if (proc == null) {
13922                Slog.e(TAG, "Unable to start backup agent process " + r);
13923                return false;
13924            }
13925
13926            r.app = proc;
13927            mBackupTarget = r;
13928            mBackupAppName = app.packageName;
13929
13930            // Try not to kill the process during backup
13931            updateOomAdjLocked(proc);
13932
13933            // If the process is already attached, schedule the creation of the backup agent now.
13934            // If it is not yet live, this will be done when it attaches to the framework.
13935            if (proc.thread != null) {
13936                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
13937                try {
13938                    proc.thread.scheduleCreateBackupAgent(app,
13939                            compatibilityInfoForPackageLocked(app), backupMode);
13940                } catch (RemoteException e) {
13941                    // Will time out on the backup manager side
13942                }
13943            } else {
13944                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
13945            }
13946            // Invariants: at this point, the target app process exists and the application
13947            // is either already running or in the process of coming up.  mBackupTarget and
13948            // mBackupAppName describe the app, so that when it binds back to the AM we
13949            // know that it's scheduled for a backup-agent operation.
13950        }
13951
13952        return true;
13953    }
13954
13955    @Override
13956    public void clearPendingBackup() {
13957        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
13958        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
13959
13960        synchronized (this) {
13961            mBackupTarget = null;
13962            mBackupAppName = null;
13963        }
13964    }
13965
13966    // A backup agent has just come up
13967    public void backupAgentCreated(String agentPackageName, IBinder agent) {
13968        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
13969                + " = " + agent);
13970
13971        synchronized(this) {
13972            if (!agentPackageName.equals(mBackupAppName)) {
13973                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
13974                return;
13975            }
13976        }
13977
13978        long oldIdent = Binder.clearCallingIdentity();
13979        try {
13980            IBackupManager bm = IBackupManager.Stub.asInterface(
13981                    ServiceManager.getService(Context.BACKUP_SERVICE));
13982            bm.agentConnected(agentPackageName, agent);
13983        } catch (RemoteException e) {
13984            // can't happen; the backup manager service is local
13985        } catch (Exception e) {
13986            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
13987            e.printStackTrace();
13988        } finally {
13989            Binder.restoreCallingIdentity(oldIdent);
13990        }
13991    }
13992
13993    // done with this agent
13994    public void unbindBackupAgent(ApplicationInfo appInfo) {
13995        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
13996        if (appInfo == null) {
13997            Slog.w(TAG, "unbind backup agent for null app");
13998            return;
13999        }
14000
14001        synchronized(this) {
14002            try {
14003                if (mBackupAppName == null) {
14004                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14005                    return;
14006                }
14007
14008                if (!mBackupAppName.equals(appInfo.packageName)) {
14009                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14010                    return;
14011                }
14012
14013                // Not backing this app up any more; reset its OOM adjustment
14014                final ProcessRecord proc = mBackupTarget.app;
14015                updateOomAdjLocked(proc);
14016
14017                // If the app crashed during backup, 'thread' will be null here
14018                if (proc.thread != null) {
14019                    try {
14020                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14021                                compatibilityInfoForPackageLocked(appInfo));
14022                    } catch (Exception e) {
14023                        Slog.e(TAG, "Exception when unbinding backup agent:");
14024                        e.printStackTrace();
14025                    }
14026                }
14027            } finally {
14028                mBackupTarget = null;
14029                mBackupAppName = null;
14030            }
14031        }
14032    }
14033    // =========================================================
14034    // BROADCASTS
14035    // =========================================================
14036
14037    private final List getStickiesLocked(String action, IntentFilter filter,
14038            List cur, int userId) {
14039        final ContentResolver resolver = mContext.getContentResolver();
14040        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14041        if (stickies == null) {
14042            return cur;
14043        }
14044        final ArrayList<Intent> list = stickies.get(action);
14045        if (list == null) {
14046            return cur;
14047        }
14048        int N = list.size();
14049        for (int i=0; i<N; i++) {
14050            Intent intent = list.get(i);
14051            if (filter.match(resolver, intent, true, TAG) >= 0) {
14052                if (cur == null) {
14053                    cur = new ArrayList<Intent>();
14054                }
14055                cur.add(intent);
14056            }
14057        }
14058        return cur;
14059    }
14060
14061    boolean isPendingBroadcastProcessLocked(int pid) {
14062        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14063                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14064    }
14065
14066    void skipPendingBroadcastLocked(int pid) {
14067            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14068            for (BroadcastQueue queue : mBroadcastQueues) {
14069                queue.skipPendingBroadcastLocked(pid);
14070            }
14071    }
14072
14073    // The app just attached; send any pending broadcasts that it should receive
14074    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14075        boolean didSomething = false;
14076        for (BroadcastQueue queue : mBroadcastQueues) {
14077            didSomething |= queue.sendPendingBroadcastsLocked(app);
14078        }
14079        return didSomething;
14080    }
14081
14082    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14083            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14084        enforceNotIsolatedCaller("registerReceiver");
14085        int callingUid;
14086        int callingPid;
14087        synchronized(this) {
14088            ProcessRecord callerApp = null;
14089            if (caller != null) {
14090                callerApp = getRecordForAppLocked(caller);
14091                if (callerApp == null) {
14092                    throw new SecurityException(
14093                            "Unable to find app for caller " + caller
14094                            + " (pid=" + Binder.getCallingPid()
14095                            + ") when registering receiver " + receiver);
14096                }
14097                if (callerApp.info.uid != Process.SYSTEM_UID &&
14098                        !callerApp.pkgList.containsKey(callerPackage) &&
14099                        !"android".equals(callerPackage)) {
14100                    throw new SecurityException("Given caller package " + callerPackage
14101                            + " is not running in process " + callerApp);
14102                }
14103                callingUid = callerApp.info.uid;
14104                callingPid = callerApp.pid;
14105            } else {
14106                callerPackage = null;
14107                callingUid = Binder.getCallingUid();
14108                callingPid = Binder.getCallingPid();
14109            }
14110
14111            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14112                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14113
14114            List allSticky = null;
14115
14116            // Look for any matching sticky broadcasts...
14117            Iterator actions = filter.actionsIterator();
14118            if (actions != null) {
14119                while (actions.hasNext()) {
14120                    String action = (String)actions.next();
14121                    allSticky = getStickiesLocked(action, filter, allSticky,
14122                            UserHandle.USER_ALL);
14123                    allSticky = getStickiesLocked(action, filter, allSticky,
14124                            UserHandle.getUserId(callingUid));
14125                }
14126            } else {
14127                allSticky = getStickiesLocked(null, filter, allSticky,
14128                        UserHandle.USER_ALL);
14129                allSticky = getStickiesLocked(null, filter, allSticky,
14130                        UserHandle.getUserId(callingUid));
14131            }
14132
14133            // The first sticky in the list is returned directly back to
14134            // the client.
14135            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14136
14137            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14138                    + ": " + sticky);
14139
14140            if (receiver == null) {
14141                return sticky;
14142            }
14143
14144            ReceiverList rl
14145                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14146            if (rl == null) {
14147                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14148                        userId, receiver);
14149                if (rl.app != null) {
14150                    rl.app.receivers.add(rl);
14151                } else {
14152                    try {
14153                        receiver.asBinder().linkToDeath(rl, 0);
14154                    } catch (RemoteException e) {
14155                        return sticky;
14156                    }
14157                    rl.linkedToDeath = true;
14158                }
14159                mRegisteredReceivers.put(receiver.asBinder(), rl);
14160            } else if (rl.uid != callingUid) {
14161                throw new IllegalArgumentException(
14162                        "Receiver requested to register for uid " + callingUid
14163                        + " was previously registered for uid " + rl.uid);
14164            } else if (rl.pid != callingPid) {
14165                throw new IllegalArgumentException(
14166                        "Receiver requested to register for pid " + callingPid
14167                        + " was previously registered for pid " + rl.pid);
14168            } else if (rl.userId != userId) {
14169                throw new IllegalArgumentException(
14170                        "Receiver requested to register for user " + userId
14171                        + " was previously registered for user " + rl.userId);
14172            }
14173            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14174                    permission, callingUid, userId);
14175            rl.add(bf);
14176            if (!bf.debugCheck()) {
14177                Slog.w(TAG, "==> For Dynamic broadast");
14178            }
14179            mReceiverResolver.addFilter(bf);
14180
14181            // Enqueue broadcasts for all existing stickies that match
14182            // this filter.
14183            if (allSticky != null) {
14184                ArrayList receivers = new ArrayList();
14185                receivers.add(bf);
14186
14187                int N = allSticky.size();
14188                for (int i=0; i<N; i++) {
14189                    Intent intent = (Intent)allSticky.get(i);
14190                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14191                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14192                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14193                            null, null, false, true, true, -1);
14194                    queue.enqueueParallelBroadcastLocked(r);
14195                    queue.scheduleBroadcastsLocked();
14196                }
14197            }
14198
14199            return sticky;
14200        }
14201    }
14202
14203    public void unregisterReceiver(IIntentReceiver receiver) {
14204        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14205
14206        final long origId = Binder.clearCallingIdentity();
14207        try {
14208            boolean doTrim = false;
14209
14210            synchronized(this) {
14211                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14212                if (rl != null) {
14213                    if (rl.curBroadcast != null) {
14214                        BroadcastRecord r = rl.curBroadcast;
14215                        final boolean doNext = finishReceiverLocked(
14216                                receiver.asBinder(), r.resultCode, r.resultData,
14217                                r.resultExtras, r.resultAbort);
14218                        if (doNext) {
14219                            doTrim = true;
14220                            r.queue.processNextBroadcast(false);
14221                        }
14222                    }
14223
14224                    if (rl.app != null) {
14225                        rl.app.receivers.remove(rl);
14226                    }
14227                    removeReceiverLocked(rl);
14228                    if (rl.linkedToDeath) {
14229                        rl.linkedToDeath = false;
14230                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14231                    }
14232                }
14233            }
14234
14235            // If we actually concluded any broadcasts, we might now be able
14236            // to trim the recipients' apps from our working set
14237            if (doTrim) {
14238                trimApplications();
14239                return;
14240            }
14241
14242        } finally {
14243            Binder.restoreCallingIdentity(origId);
14244        }
14245    }
14246
14247    void removeReceiverLocked(ReceiverList rl) {
14248        mRegisteredReceivers.remove(rl.receiver.asBinder());
14249        int N = rl.size();
14250        for (int i=0; i<N; i++) {
14251            mReceiverResolver.removeFilter(rl.get(i));
14252        }
14253    }
14254
14255    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14256        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14257            ProcessRecord r = mLruProcesses.get(i);
14258            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14259                try {
14260                    r.thread.dispatchPackageBroadcast(cmd, packages);
14261                } catch (RemoteException ex) {
14262                }
14263            }
14264        }
14265    }
14266
14267    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14268            int[] users) {
14269        List<ResolveInfo> receivers = null;
14270        try {
14271            HashSet<ComponentName> singleUserReceivers = null;
14272            boolean scannedFirstReceivers = false;
14273            for (int user : users) {
14274                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
14275                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
14276                if (user != 0 && newReceivers != null) {
14277                    // If this is not the primary user, we need to check for
14278                    // any receivers that should be filtered out.
14279                    for (int i=0; i<newReceivers.size(); i++) {
14280                        ResolveInfo ri = newReceivers.get(i);
14281                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
14282                            newReceivers.remove(i);
14283                            i--;
14284                        }
14285                    }
14286                }
14287                if (newReceivers != null && newReceivers.size() == 0) {
14288                    newReceivers = null;
14289                }
14290                if (receivers == null) {
14291                    receivers = newReceivers;
14292                } else if (newReceivers != null) {
14293                    // We need to concatenate the additional receivers
14294                    // found with what we have do far.  This would be easy,
14295                    // but we also need to de-dup any receivers that are
14296                    // singleUser.
14297                    if (!scannedFirstReceivers) {
14298                        // Collect any single user receivers we had already retrieved.
14299                        scannedFirstReceivers = true;
14300                        for (int i=0; i<receivers.size(); i++) {
14301                            ResolveInfo ri = receivers.get(i);
14302                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14303                                ComponentName cn = new ComponentName(
14304                                        ri.activityInfo.packageName, ri.activityInfo.name);
14305                                if (singleUserReceivers == null) {
14306                                    singleUserReceivers = new HashSet<ComponentName>();
14307                                }
14308                                singleUserReceivers.add(cn);
14309                            }
14310                        }
14311                    }
14312                    // Add the new results to the existing results, tracking
14313                    // and de-dupping single user receivers.
14314                    for (int i=0; i<newReceivers.size(); i++) {
14315                        ResolveInfo ri = newReceivers.get(i);
14316                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
14317                            ComponentName cn = new ComponentName(
14318                                    ri.activityInfo.packageName, ri.activityInfo.name);
14319                            if (singleUserReceivers == null) {
14320                                singleUserReceivers = new HashSet<ComponentName>();
14321                            }
14322                            if (!singleUserReceivers.contains(cn)) {
14323                                singleUserReceivers.add(cn);
14324                                receivers.add(ri);
14325                            }
14326                        } else {
14327                            receivers.add(ri);
14328                        }
14329                    }
14330                }
14331            }
14332        } catch (RemoteException ex) {
14333            // pm is in same process, this will never happen.
14334        }
14335        return receivers;
14336    }
14337
14338    private final int broadcastIntentLocked(ProcessRecord callerApp,
14339            String callerPackage, Intent intent, String resolvedType,
14340            IIntentReceiver resultTo, int resultCode, String resultData,
14341            Bundle map, String requiredPermission, int appOp,
14342            boolean ordered, boolean sticky, int callingPid, int callingUid,
14343            int userId) {
14344        intent = new Intent(intent);
14345
14346        // By default broadcasts do not go to stopped apps.
14347        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
14348
14349        if (DEBUG_BROADCAST_LIGHT) Slog.v(
14350            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
14351            + " ordered=" + ordered + " userid=" + userId);
14352        if ((resultTo != null) && !ordered) {
14353            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
14354        }
14355
14356        userId = handleIncomingUser(callingPid, callingUid, userId,
14357                true, ALLOW_NON_FULL, "broadcast", callerPackage);
14358
14359        // Make sure that the user who is receiving this broadcast is started.
14360        // If not, we will just skip it.
14361
14362
14363        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
14364            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
14365                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
14366                Slog.w(TAG, "Skipping broadcast of " + intent
14367                        + ": user " + userId + " is stopped");
14368                return ActivityManager.BROADCAST_SUCCESS;
14369            }
14370        }
14371
14372        /*
14373         * Prevent non-system code (defined here to be non-persistent
14374         * processes) from sending protected broadcasts.
14375         */
14376        int callingAppId = UserHandle.getAppId(callingUid);
14377        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
14378            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
14379            || callingAppId == Process.NFC_UID || callingUid == 0) {
14380            // Always okay.
14381        } else if (callerApp == null || !callerApp.persistent) {
14382            try {
14383                if (AppGlobals.getPackageManager().isProtectedBroadcast(
14384                        intent.getAction())) {
14385                    String msg = "Permission Denial: not allowed to send broadcast "
14386                            + intent.getAction() + " from pid="
14387                            + callingPid + ", uid=" + callingUid;
14388                    Slog.w(TAG, msg);
14389                    throw new SecurityException(msg);
14390                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
14391                    // Special case for compatibility: we don't want apps to send this,
14392                    // but historically it has not been protected and apps may be using it
14393                    // to poke their own app widget.  So, instead of making it protected,
14394                    // just limit it to the caller.
14395                    if (callerApp == null) {
14396                        String msg = "Permission Denial: not allowed to send broadcast "
14397                                + intent.getAction() + " from unknown caller.";
14398                        Slog.w(TAG, msg);
14399                        throw new SecurityException(msg);
14400                    } else if (intent.getComponent() != null) {
14401                        // They are good enough to send to an explicit component...  verify
14402                        // it is being sent to the calling app.
14403                        if (!intent.getComponent().getPackageName().equals(
14404                                callerApp.info.packageName)) {
14405                            String msg = "Permission Denial: not allowed to send broadcast "
14406                                    + intent.getAction() + " to "
14407                                    + intent.getComponent().getPackageName() + " from "
14408                                    + callerApp.info.packageName;
14409                            Slog.w(TAG, msg);
14410                            throw new SecurityException(msg);
14411                        }
14412                    } else {
14413                        // Limit broadcast to their own package.
14414                        intent.setPackage(callerApp.info.packageName);
14415                    }
14416                }
14417            } catch (RemoteException e) {
14418                Slog.w(TAG, "Remote exception", e);
14419                return ActivityManager.BROADCAST_SUCCESS;
14420            }
14421        }
14422
14423        // Handle special intents: if this broadcast is from the package
14424        // manager about a package being removed, we need to remove all of
14425        // its activities from the history stack.
14426        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
14427                intent.getAction());
14428        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
14429                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
14430                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
14431                || uidRemoved) {
14432            if (checkComponentPermission(
14433                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
14434                    callingPid, callingUid, -1, true)
14435                    == PackageManager.PERMISSION_GRANTED) {
14436                if (uidRemoved) {
14437                    final Bundle intentExtras = intent.getExtras();
14438                    final int uid = intentExtras != null
14439                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
14440                    if (uid >= 0) {
14441                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
14442                        synchronized (bs) {
14443                            bs.removeUidStatsLocked(uid);
14444                        }
14445                        mAppOpsService.uidRemoved(uid);
14446                    }
14447                } else {
14448                    // If resources are unavailable just force stop all
14449                    // those packages and flush the attribute cache as well.
14450                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
14451                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14452                        if (list != null && (list.length > 0)) {
14453                            for (String pkg : list) {
14454                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
14455                                        "storage unmount");
14456                            }
14457                            sendPackageBroadcastLocked(
14458                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
14459                        }
14460                    } else {
14461                        Uri data = intent.getData();
14462                        String ssp;
14463                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14464                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
14465                                    intent.getAction());
14466                            boolean fullUninstall = removed &&
14467                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
14468                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
14469                                forceStopPackageLocked(ssp, UserHandle.getAppId(
14470                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
14471                                        false, fullUninstall, userId,
14472                                        removed ? "pkg removed" : "pkg changed");
14473                            }
14474                            if (removed) {
14475                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
14476                                        new String[] {ssp}, userId);
14477                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
14478                                    mAppOpsService.packageRemoved(
14479                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
14480
14481                                    // Remove all permissions granted from/to this package
14482                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
14483                                }
14484                            }
14485                        }
14486                    }
14487                }
14488            } else {
14489                String msg = "Permission Denial: " + intent.getAction()
14490                        + " broadcast from " + callerPackage + " (pid=" + callingPid
14491                        + ", uid=" + callingUid + ")"
14492                        + " requires "
14493                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
14494                Slog.w(TAG, msg);
14495                throw new SecurityException(msg);
14496            }
14497
14498        // Special case for adding a package: by default turn on compatibility
14499        // mode.
14500        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
14501            Uri data = intent.getData();
14502            String ssp;
14503            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
14504                mCompatModePackages.handlePackageAddedLocked(ssp,
14505                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
14506            }
14507        }
14508
14509        /*
14510         * If this is the time zone changed action, queue up a message that will reset the timezone
14511         * of all currently running processes. This message will get queued up before the broadcast
14512         * happens.
14513         */
14514        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
14515            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
14516        }
14517
14518        /*
14519         * If the user set the time, let all running processes know.
14520         */
14521        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
14522            final int is24Hour = intent.getBooleanExtra(
14523                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
14524            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
14525        }
14526
14527        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
14528            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
14529        }
14530
14531        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
14532            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
14533            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
14534        }
14535
14536        // Add to the sticky list if requested.
14537        if (sticky) {
14538            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
14539                    callingPid, callingUid)
14540                    != PackageManager.PERMISSION_GRANTED) {
14541                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
14542                        + callingPid + ", uid=" + callingUid
14543                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14544                Slog.w(TAG, msg);
14545                throw new SecurityException(msg);
14546            }
14547            if (requiredPermission != null) {
14548                Slog.w(TAG, "Can't broadcast sticky intent " + intent
14549                        + " and enforce permission " + requiredPermission);
14550                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
14551            }
14552            if (intent.getComponent() != null) {
14553                throw new SecurityException(
14554                        "Sticky broadcasts can't target a specific component");
14555            }
14556            // We use userId directly here, since the "all" target is maintained
14557            // as a separate set of sticky broadcasts.
14558            if (userId != UserHandle.USER_ALL) {
14559                // But first, if this is not a broadcast to all users, then
14560                // make sure it doesn't conflict with an existing broadcast to
14561                // all users.
14562                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
14563                        UserHandle.USER_ALL);
14564                if (stickies != null) {
14565                    ArrayList<Intent> list = stickies.get(intent.getAction());
14566                    if (list != null) {
14567                        int N = list.size();
14568                        int i;
14569                        for (i=0; i<N; i++) {
14570                            if (intent.filterEquals(list.get(i))) {
14571                                throw new IllegalArgumentException(
14572                                        "Sticky broadcast " + intent + " for user "
14573                                        + userId + " conflicts with existing global broadcast");
14574                            }
14575                        }
14576                    }
14577                }
14578            }
14579            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14580            if (stickies == null) {
14581                stickies = new ArrayMap<String, ArrayList<Intent>>();
14582                mStickyBroadcasts.put(userId, stickies);
14583            }
14584            ArrayList<Intent> list = stickies.get(intent.getAction());
14585            if (list == null) {
14586                list = new ArrayList<Intent>();
14587                stickies.put(intent.getAction(), list);
14588            }
14589            int N = list.size();
14590            int i;
14591            for (i=0; i<N; i++) {
14592                if (intent.filterEquals(list.get(i))) {
14593                    // This sticky already exists, replace it.
14594                    list.set(i, new Intent(intent));
14595                    break;
14596                }
14597            }
14598            if (i >= N) {
14599                list.add(new Intent(intent));
14600            }
14601        }
14602
14603        int[] users;
14604        if (userId == UserHandle.USER_ALL) {
14605            // Caller wants broadcast to go to all started users.
14606            users = mStartedUserArray;
14607        } else {
14608            // Caller wants broadcast to go to one specific user.
14609            users = new int[] {userId};
14610        }
14611
14612        // Figure out who all will receive this broadcast.
14613        List receivers = null;
14614        List<BroadcastFilter> registeredReceivers = null;
14615        // Need to resolve the intent to interested receivers...
14616        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
14617                 == 0) {
14618            receivers = collectReceiverComponents(intent, resolvedType, users);
14619        }
14620        if (intent.getComponent() == null) {
14621            registeredReceivers = mReceiverResolver.queryIntent(intent,
14622                    resolvedType, false, userId);
14623        }
14624
14625        final boolean replacePending =
14626                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
14627
14628        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
14629                + " replacePending=" + replacePending);
14630
14631        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
14632        if (!ordered && NR > 0) {
14633            // If we are not serializing this broadcast, then send the
14634            // registered receivers separately so they don't wait for the
14635            // components to be launched.
14636            final BroadcastQueue queue = broadcastQueueForIntent(intent);
14637            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14638                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
14639                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
14640                    ordered, sticky, false, userId);
14641            if (DEBUG_BROADCAST) Slog.v(
14642                    TAG, "Enqueueing parallel broadcast " + r);
14643            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
14644            if (!replaced) {
14645                queue.enqueueParallelBroadcastLocked(r);
14646                queue.scheduleBroadcastsLocked();
14647            }
14648            registeredReceivers = null;
14649            NR = 0;
14650        }
14651
14652        // Merge into one list.
14653        int ir = 0;
14654        if (receivers != null) {
14655            // A special case for PACKAGE_ADDED: do not allow the package
14656            // being added to see this broadcast.  This prevents them from
14657            // using this as a back door to get run as soon as they are
14658            // installed.  Maybe in the future we want to have a special install
14659            // broadcast or such for apps, but we'd like to deliberately make
14660            // this decision.
14661            String skipPackages[] = null;
14662            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
14663                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
14664                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
14665                Uri data = intent.getData();
14666                if (data != null) {
14667                    String pkgName = data.getSchemeSpecificPart();
14668                    if (pkgName != null) {
14669                        skipPackages = new String[] { pkgName };
14670                    }
14671                }
14672            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
14673                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
14674            }
14675            if (skipPackages != null && (skipPackages.length > 0)) {
14676                for (String skipPackage : skipPackages) {
14677                    if (skipPackage != null) {
14678                        int NT = receivers.size();
14679                        for (int it=0; it<NT; it++) {
14680                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
14681                            if (curt.activityInfo.packageName.equals(skipPackage)) {
14682                                receivers.remove(it);
14683                                it--;
14684                                NT--;
14685                            }
14686                        }
14687                    }
14688                }
14689            }
14690
14691            int NT = receivers != null ? receivers.size() : 0;
14692            int it = 0;
14693            ResolveInfo curt = null;
14694            BroadcastFilter curr = null;
14695            while (it < NT && ir < NR) {
14696                if (curt == null) {
14697                    curt = (ResolveInfo)receivers.get(it);
14698                }
14699                if (curr == null) {
14700                    curr = registeredReceivers.get(ir);
14701                }
14702                if (curr.getPriority() >= curt.priority) {
14703                    // Insert this broadcast record into the final list.
14704                    receivers.add(it, curr);
14705                    ir++;
14706                    curr = null;
14707                    it++;
14708                    NT++;
14709                } else {
14710                    // Skip to the next ResolveInfo in the final list.
14711                    it++;
14712                    curt = null;
14713                }
14714            }
14715        }
14716        while (ir < NR) {
14717            if (receivers == null) {
14718                receivers = new ArrayList();
14719            }
14720            receivers.add(registeredReceivers.get(ir));
14721            ir++;
14722        }
14723
14724        if ((receivers != null && receivers.size() > 0)
14725                || resultTo != null) {
14726            BroadcastQueue queue = broadcastQueueForIntent(intent);
14727            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
14728                    callerPackage, callingPid, callingUid, resolvedType,
14729                    requiredPermission, appOp, receivers, resultTo, resultCode,
14730                    resultData, map, ordered, sticky, false, userId);
14731            if (DEBUG_BROADCAST) Slog.v(
14732                    TAG, "Enqueueing ordered broadcast " + r
14733                    + ": prev had " + queue.mOrderedBroadcasts.size());
14734            if (DEBUG_BROADCAST) {
14735                int seq = r.intent.getIntExtra("seq", -1);
14736                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
14737            }
14738            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
14739            if (!replaced) {
14740                queue.enqueueOrderedBroadcastLocked(r);
14741                queue.scheduleBroadcastsLocked();
14742            }
14743        }
14744
14745        return ActivityManager.BROADCAST_SUCCESS;
14746    }
14747
14748    final Intent verifyBroadcastLocked(Intent intent) {
14749        // Refuse possible leaked file descriptors
14750        if (intent != null && intent.hasFileDescriptors() == true) {
14751            throw new IllegalArgumentException("File descriptors passed in Intent");
14752        }
14753
14754        int flags = intent.getFlags();
14755
14756        if (!mProcessesReady) {
14757            // if the caller really truly claims to know what they're doing, go
14758            // ahead and allow the broadcast without launching any receivers
14759            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
14760                intent = new Intent(intent);
14761                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14762            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
14763                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
14764                        + " before boot completion");
14765                throw new IllegalStateException("Cannot broadcast before boot completed");
14766            }
14767        }
14768
14769        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
14770            throw new IllegalArgumentException(
14771                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
14772        }
14773
14774        return intent;
14775    }
14776
14777    public final int broadcastIntent(IApplicationThread caller,
14778            Intent intent, String resolvedType, IIntentReceiver resultTo,
14779            int resultCode, String resultData, Bundle map,
14780            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
14781        enforceNotIsolatedCaller("broadcastIntent");
14782        synchronized(this) {
14783            intent = verifyBroadcastLocked(intent);
14784
14785            final ProcessRecord callerApp = getRecordForAppLocked(caller);
14786            final int callingPid = Binder.getCallingPid();
14787            final int callingUid = Binder.getCallingUid();
14788            final long origId = Binder.clearCallingIdentity();
14789            int res = broadcastIntentLocked(callerApp,
14790                    callerApp != null ? callerApp.info.packageName : null,
14791                    intent, resolvedType, resultTo,
14792                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
14793                    callingPid, callingUid, userId);
14794            Binder.restoreCallingIdentity(origId);
14795            return res;
14796        }
14797    }
14798
14799    int broadcastIntentInPackage(String packageName, int uid,
14800            Intent intent, String resolvedType, IIntentReceiver resultTo,
14801            int resultCode, String resultData, Bundle map,
14802            String requiredPermission, boolean serialized, boolean sticky, int userId) {
14803        synchronized(this) {
14804            intent = verifyBroadcastLocked(intent);
14805
14806            final long origId = Binder.clearCallingIdentity();
14807            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
14808                    resultTo, resultCode, resultData, map, requiredPermission,
14809                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
14810            Binder.restoreCallingIdentity(origId);
14811            return res;
14812        }
14813    }
14814
14815    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
14816        // Refuse possible leaked file descriptors
14817        if (intent != null && intent.hasFileDescriptors() == true) {
14818            throw new IllegalArgumentException("File descriptors passed in Intent");
14819        }
14820
14821        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14822                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
14823
14824        synchronized(this) {
14825            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
14826                    != PackageManager.PERMISSION_GRANTED) {
14827                String msg = "Permission Denial: unbroadcastIntent() from pid="
14828                        + Binder.getCallingPid()
14829                        + ", uid=" + Binder.getCallingUid()
14830                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
14831                Slog.w(TAG, msg);
14832                throw new SecurityException(msg);
14833            }
14834            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14835            if (stickies != null) {
14836                ArrayList<Intent> list = stickies.get(intent.getAction());
14837                if (list != null) {
14838                    int N = list.size();
14839                    int i;
14840                    for (i=0; i<N; i++) {
14841                        if (intent.filterEquals(list.get(i))) {
14842                            list.remove(i);
14843                            break;
14844                        }
14845                    }
14846                    if (list.size() <= 0) {
14847                        stickies.remove(intent.getAction());
14848                    }
14849                }
14850                if (stickies.size() <= 0) {
14851                    mStickyBroadcasts.remove(userId);
14852                }
14853            }
14854        }
14855    }
14856
14857    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
14858            String resultData, Bundle resultExtras, boolean resultAbort) {
14859        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
14860        if (r == null) {
14861            Slog.w(TAG, "finishReceiver called but not found on queue");
14862            return false;
14863        }
14864
14865        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
14866    }
14867
14868    void backgroundServicesFinishedLocked(int userId) {
14869        for (BroadcastQueue queue : mBroadcastQueues) {
14870            queue.backgroundServicesFinishedLocked(userId);
14871        }
14872    }
14873
14874    public void finishReceiver(IBinder who, int resultCode, String resultData,
14875            Bundle resultExtras, boolean resultAbort) {
14876        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
14877
14878        // Refuse possible leaked file descriptors
14879        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
14880            throw new IllegalArgumentException("File descriptors passed in Bundle");
14881        }
14882
14883        final long origId = Binder.clearCallingIdentity();
14884        try {
14885            boolean doNext = false;
14886            BroadcastRecord r;
14887
14888            synchronized(this) {
14889                r = broadcastRecordForReceiverLocked(who);
14890                if (r != null) {
14891                    doNext = r.queue.finishReceiverLocked(r, resultCode,
14892                        resultData, resultExtras, resultAbort, true);
14893                }
14894            }
14895
14896            if (doNext) {
14897                r.queue.processNextBroadcast(false);
14898            }
14899            trimApplications();
14900        } finally {
14901            Binder.restoreCallingIdentity(origId);
14902        }
14903    }
14904
14905    // =========================================================
14906    // INSTRUMENTATION
14907    // =========================================================
14908
14909    public boolean startInstrumentation(ComponentName className,
14910            String profileFile, int flags, Bundle arguments,
14911            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
14912            int userId, String abiOverride) {
14913        enforceNotIsolatedCaller("startInstrumentation");
14914        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
14915                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
14916        // Refuse possible leaked file descriptors
14917        if (arguments != null && arguments.hasFileDescriptors()) {
14918            throw new IllegalArgumentException("File descriptors passed in Bundle");
14919        }
14920
14921        synchronized(this) {
14922            InstrumentationInfo ii = null;
14923            ApplicationInfo ai = null;
14924            try {
14925                ii = mContext.getPackageManager().getInstrumentationInfo(
14926                    className, STOCK_PM_FLAGS);
14927                ai = AppGlobals.getPackageManager().getApplicationInfo(
14928                        ii.targetPackage, STOCK_PM_FLAGS, userId);
14929            } catch (PackageManager.NameNotFoundException e) {
14930            } catch (RemoteException e) {
14931            }
14932            if (ii == null) {
14933                reportStartInstrumentationFailure(watcher, className,
14934                        "Unable to find instrumentation info for: " + className);
14935                return false;
14936            }
14937            if (ai == null) {
14938                reportStartInstrumentationFailure(watcher, className,
14939                        "Unable to find instrumentation target package: " + ii.targetPackage);
14940                return false;
14941            }
14942
14943            int match = mContext.getPackageManager().checkSignatures(
14944                    ii.targetPackage, ii.packageName);
14945            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
14946                String msg = "Permission Denial: starting instrumentation "
14947                        + className + " from pid="
14948                        + Binder.getCallingPid()
14949                        + ", uid=" + Binder.getCallingPid()
14950                        + " not allowed because package " + ii.packageName
14951                        + " does not have a signature matching the target "
14952                        + ii.targetPackage;
14953                reportStartInstrumentationFailure(watcher, className, msg);
14954                throw new SecurityException(msg);
14955            }
14956
14957            final long origId = Binder.clearCallingIdentity();
14958            // Instrumentation can kill and relaunch even persistent processes
14959            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
14960                    "start instr");
14961            ProcessRecord app = addAppLocked(ai, false, abiOverride);
14962            app.instrumentationClass = className;
14963            app.instrumentationInfo = ai;
14964            app.instrumentationProfileFile = profileFile;
14965            app.instrumentationArguments = arguments;
14966            app.instrumentationWatcher = watcher;
14967            app.instrumentationUiAutomationConnection = uiAutomationConnection;
14968            app.instrumentationResultClass = className;
14969            Binder.restoreCallingIdentity(origId);
14970        }
14971
14972        return true;
14973    }
14974
14975    /**
14976     * Report errors that occur while attempting to start Instrumentation.  Always writes the
14977     * error to the logs, but if somebody is watching, send the report there too.  This enables
14978     * the "am" command to report errors with more information.
14979     *
14980     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
14981     * @param cn The component name of the instrumentation.
14982     * @param report The error report.
14983     */
14984    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
14985            ComponentName cn, String report) {
14986        Slog.w(TAG, report);
14987        try {
14988            if (watcher != null) {
14989                Bundle results = new Bundle();
14990                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
14991                results.putString("Error", report);
14992                watcher.instrumentationStatus(cn, -1, results);
14993            }
14994        } catch (RemoteException e) {
14995            Slog.w(TAG, e);
14996        }
14997    }
14998
14999    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15000        if (app.instrumentationWatcher != null) {
15001            try {
15002                // NOTE:  IInstrumentationWatcher *must* be oneway here
15003                app.instrumentationWatcher.instrumentationFinished(
15004                    app.instrumentationClass,
15005                    resultCode,
15006                    results);
15007            } catch (RemoteException e) {
15008            }
15009        }
15010        if (app.instrumentationUiAutomationConnection != null) {
15011            try {
15012                app.instrumentationUiAutomationConnection.shutdown();
15013            } catch (RemoteException re) {
15014                /* ignore */
15015            }
15016            // Only a UiAutomation can set this flag and now that
15017            // it is finished we make sure it is reset to its default.
15018            mUserIsMonkey = false;
15019        }
15020        app.instrumentationWatcher = null;
15021        app.instrumentationUiAutomationConnection = null;
15022        app.instrumentationClass = null;
15023        app.instrumentationInfo = null;
15024        app.instrumentationProfileFile = null;
15025        app.instrumentationArguments = null;
15026
15027        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15028                "finished inst");
15029    }
15030
15031    public void finishInstrumentation(IApplicationThread target,
15032            int resultCode, Bundle results) {
15033        int userId = UserHandle.getCallingUserId();
15034        // Refuse possible leaked file descriptors
15035        if (results != null && results.hasFileDescriptors()) {
15036            throw new IllegalArgumentException("File descriptors passed in Intent");
15037        }
15038
15039        synchronized(this) {
15040            ProcessRecord app = getRecordForAppLocked(target);
15041            if (app == null) {
15042                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15043                return;
15044            }
15045            final long origId = Binder.clearCallingIdentity();
15046            finishInstrumentationLocked(app, resultCode, results);
15047            Binder.restoreCallingIdentity(origId);
15048        }
15049    }
15050
15051    // =========================================================
15052    // CONFIGURATION
15053    // =========================================================
15054
15055    public ConfigurationInfo getDeviceConfigurationInfo() {
15056        ConfigurationInfo config = new ConfigurationInfo();
15057        synchronized (this) {
15058            config.reqTouchScreen = mConfiguration.touchscreen;
15059            config.reqKeyboardType = mConfiguration.keyboard;
15060            config.reqNavigation = mConfiguration.navigation;
15061            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15062                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15063                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15064            }
15065            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15066                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15067                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15068            }
15069            config.reqGlEsVersion = GL_ES_VERSION;
15070        }
15071        return config;
15072    }
15073
15074    ActivityStack getFocusedStack() {
15075        return mStackSupervisor.getFocusedStack();
15076    }
15077
15078    public Configuration getConfiguration() {
15079        Configuration ci;
15080        synchronized(this) {
15081            ci = new Configuration(mConfiguration);
15082        }
15083        return ci;
15084    }
15085
15086    public void updatePersistentConfiguration(Configuration values) {
15087        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15088                "updateConfiguration()");
15089        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15090                "updateConfiguration()");
15091        if (values == null) {
15092            throw new NullPointerException("Configuration must not be null");
15093        }
15094
15095        synchronized(this) {
15096            final long origId = Binder.clearCallingIdentity();
15097            updateConfigurationLocked(values, null, true, false);
15098            Binder.restoreCallingIdentity(origId);
15099        }
15100    }
15101
15102    public void updateConfiguration(Configuration values) {
15103        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15104                "updateConfiguration()");
15105
15106        synchronized(this) {
15107            if (values == null && mWindowManager != null) {
15108                // sentinel: fetch the current configuration from the window manager
15109                values = mWindowManager.computeNewConfiguration();
15110            }
15111
15112            if (mWindowManager != null) {
15113                mProcessList.applyDisplaySize(mWindowManager);
15114            }
15115
15116            final long origId = Binder.clearCallingIdentity();
15117            if (values != null) {
15118                Settings.System.clearConfiguration(values);
15119            }
15120            updateConfigurationLocked(values, null, false, false);
15121            Binder.restoreCallingIdentity(origId);
15122        }
15123    }
15124
15125    /**
15126     * Do either or both things: (1) change the current configuration, and (2)
15127     * make sure the given activity is running with the (now) current
15128     * configuration.  Returns true if the activity has been left running, or
15129     * false if <var>starting</var> is being destroyed to match the new
15130     * configuration.
15131     * @param persistent TODO
15132     */
15133    boolean updateConfigurationLocked(Configuration values,
15134            ActivityRecord starting, boolean persistent, boolean initLocale) {
15135        int changes = 0;
15136
15137        if (values != null) {
15138            Configuration newConfig = new Configuration(mConfiguration);
15139            changes = newConfig.updateFrom(values);
15140            if (changes != 0) {
15141                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15142                    Slog.i(TAG, "Updating configuration to: " + values);
15143                }
15144
15145                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15146
15147                if (values.locale != null && !initLocale) {
15148                    saveLocaleLocked(values.locale,
15149                                     !values.locale.equals(mConfiguration.locale),
15150                                     values.userSetLocale);
15151                }
15152
15153                mConfigurationSeq++;
15154                if (mConfigurationSeq <= 0) {
15155                    mConfigurationSeq = 1;
15156                }
15157                newConfig.seq = mConfigurationSeq;
15158                mConfiguration = newConfig;
15159                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15160                //mUsageStatsService.noteStartConfig(newConfig);
15161
15162                final Configuration configCopy = new Configuration(mConfiguration);
15163
15164                // TODO: If our config changes, should we auto dismiss any currently
15165                // showing dialogs?
15166                mShowDialogs = shouldShowDialogs(newConfig);
15167
15168                AttributeCache ac = AttributeCache.instance();
15169                if (ac != null) {
15170                    ac.updateConfiguration(configCopy);
15171                }
15172
15173                // Make sure all resources in our process are updated
15174                // right now, so that anyone who is going to retrieve
15175                // resource values after we return will be sure to get
15176                // the new ones.  This is especially important during
15177                // boot, where the first config change needs to guarantee
15178                // all resources have that config before following boot
15179                // code is executed.
15180                mSystemThread.applyConfigurationToResources(configCopy);
15181
15182                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15183                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15184                    msg.obj = new Configuration(configCopy);
15185                    mHandler.sendMessage(msg);
15186                }
15187
15188                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15189                    ProcessRecord app = mLruProcesses.get(i);
15190                    try {
15191                        if (app.thread != null) {
15192                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15193                                    + app.processName + " new config " + mConfiguration);
15194                            app.thread.scheduleConfigurationChanged(configCopy);
15195                        }
15196                    } catch (Exception e) {
15197                    }
15198                }
15199                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15200                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15201                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15202                        | Intent.FLAG_RECEIVER_FOREGROUND);
15203                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15204                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15205                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15206                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15207                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15208                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15209                    broadcastIntentLocked(null, null, intent,
15210                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15211                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15212                }
15213            }
15214        }
15215
15216        boolean kept = true;
15217        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15218        // mainStack is null during startup.
15219        if (mainStack != null) {
15220            if (changes != 0 && starting == null) {
15221                // If the configuration changed, and the caller is not already
15222                // in the process of starting an activity, then find the top
15223                // activity to check if its configuration needs to change.
15224                starting = mainStack.topRunningActivityLocked(null);
15225            }
15226
15227            if (starting != null) {
15228                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15229                // And we need to make sure at this point that all other activities
15230                // are made visible with the correct configuration.
15231                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15232            }
15233        }
15234
15235        if (values != null && mWindowManager != null) {
15236            mWindowManager.setNewConfiguration(mConfiguration);
15237        }
15238
15239        return kept;
15240    }
15241
15242    /**
15243     * Decide based on the configuration whether we should shouw the ANR,
15244     * crash, etc dialogs.  The idea is that if there is no affordnace to
15245     * press the on-screen buttons, we shouldn't show the dialog.
15246     *
15247     * A thought: SystemUI might also want to get told about this, the Power
15248     * dialog / global actions also might want different behaviors.
15249     */
15250    private static final boolean shouldShowDialogs(Configuration config) {
15251        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15252                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15253    }
15254
15255    /**
15256     * Save the locale.  You must be inside a synchronized (this) block.
15257     */
15258    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15259        if(isDiff) {
15260            SystemProperties.set("user.language", l.getLanguage());
15261            SystemProperties.set("user.region", l.getCountry());
15262        }
15263
15264        if(isPersist) {
15265            SystemProperties.set("persist.sys.language", l.getLanguage());
15266            SystemProperties.set("persist.sys.country", l.getCountry());
15267            SystemProperties.set("persist.sys.localevar", l.getVariant());
15268        }
15269    }
15270
15271    @Override
15272    public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
15273        ActivityRecord srec = ActivityRecord.forToken(token);
15274        return srec != null && srec.task.affinity != null &&
15275                srec.task.affinity.equals(destAffinity);
15276    }
15277
15278    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
15279            Intent resultData) {
15280
15281        synchronized (this) {
15282            final ActivityStack stack = ActivityRecord.getStackLocked(token);
15283            if (stack != null) {
15284                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
15285            }
15286            return false;
15287        }
15288    }
15289
15290    public int getLaunchedFromUid(IBinder activityToken) {
15291        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15292        if (srec == null) {
15293            return -1;
15294        }
15295        return srec.launchedFromUid;
15296    }
15297
15298    public String getLaunchedFromPackage(IBinder activityToken) {
15299        ActivityRecord srec = ActivityRecord.forToken(activityToken);
15300        if (srec == null) {
15301            return null;
15302        }
15303        return srec.launchedFromPackage;
15304    }
15305
15306    // =========================================================
15307    // LIFETIME MANAGEMENT
15308    // =========================================================
15309
15310    // Returns which broadcast queue the app is the current [or imminent] receiver
15311    // on, or 'null' if the app is not an active broadcast recipient.
15312    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
15313        BroadcastRecord r = app.curReceiver;
15314        if (r != null) {
15315            return r.queue;
15316        }
15317
15318        // It's not the current receiver, but it might be starting up to become one
15319        synchronized (this) {
15320            for (BroadcastQueue queue : mBroadcastQueues) {
15321                r = queue.mPendingBroadcast;
15322                if (r != null && r.curApp == app) {
15323                    // found it; report which queue it's in
15324                    return queue;
15325                }
15326            }
15327        }
15328
15329        return null;
15330    }
15331
15332    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
15333            boolean doingAll, long now) {
15334        if (mAdjSeq == app.adjSeq) {
15335            // This adjustment has already been computed.
15336            return app.curRawAdj;
15337        }
15338
15339        if (app.thread == null) {
15340            app.adjSeq = mAdjSeq;
15341            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15342            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15343            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
15344        }
15345
15346        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
15347        app.adjSource = null;
15348        app.adjTarget = null;
15349        app.empty = false;
15350        app.cached = false;
15351
15352        final int activitiesSize = app.activities.size();
15353
15354        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15355            // The max adjustment doesn't allow this app to be anything
15356            // below foreground, so it is not worth doing work for it.
15357            app.adjType = "fixed";
15358            app.adjSeq = mAdjSeq;
15359            app.curRawAdj = app.maxAdj;
15360            app.foregroundActivities = false;
15361            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
15362            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
15363            // System processes can do UI, and when they do we want to have
15364            // them trim their memory after the user leaves the UI.  To
15365            // facilitate this, here we need to determine whether or not it
15366            // is currently showing UI.
15367            app.systemNoUi = true;
15368            if (app == TOP_APP) {
15369                app.systemNoUi = false;
15370            } else if (activitiesSize > 0) {
15371                for (int j = 0; j < activitiesSize; j++) {
15372                    final ActivityRecord r = app.activities.get(j);
15373                    if (r.visible) {
15374                        app.systemNoUi = false;
15375                    }
15376                }
15377            }
15378            if (!app.systemNoUi) {
15379                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
15380            }
15381            return (app.curAdj=app.maxAdj);
15382        }
15383
15384        app.systemNoUi = false;
15385
15386        // Determine the importance of the process, starting with most
15387        // important to least, and assign an appropriate OOM adjustment.
15388        int adj;
15389        int schedGroup;
15390        int procState;
15391        boolean foregroundActivities = false;
15392        BroadcastQueue queue;
15393        if (app == TOP_APP) {
15394            // The last app on the list is the foreground app.
15395            adj = ProcessList.FOREGROUND_APP_ADJ;
15396            schedGroup = Process.THREAD_GROUP_DEFAULT;
15397            app.adjType = "top-activity";
15398            foregroundActivities = true;
15399            procState = ActivityManager.PROCESS_STATE_TOP;
15400        } else if (app.instrumentationClass != null) {
15401            // Don't want to kill running instrumentation.
15402            adj = ProcessList.FOREGROUND_APP_ADJ;
15403            schedGroup = Process.THREAD_GROUP_DEFAULT;
15404            app.adjType = "instrumentation";
15405            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15406        } else if ((queue = isReceivingBroadcast(app)) != null) {
15407            // An app that is currently receiving a broadcast also
15408            // counts as being in the foreground for OOM killer purposes.
15409            // It's placed in a sched group based on the nature of the
15410            // broadcast as reflected by which queue it's active in.
15411            adj = ProcessList.FOREGROUND_APP_ADJ;
15412            schedGroup = (queue == mFgBroadcastQueue)
15413                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15414            app.adjType = "broadcast";
15415            procState = ActivityManager.PROCESS_STATE_RECEIVER;
15416        } else if (app.executingServices.size() > 0) {
15417            // An app that is currently executing a service callback also
15418            // counts as being in the foreground.
15419            adj = ProcessList.FOREGROUND_APP_ADJ;
15420            schedGroup = app.execServicesFg ?
15421                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
15422            app.adjType = "exec-service";
15423            procState = ActivityManager.PROCESS_STATE_SERVICE;
15424            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
15425        } else {
15426            // As far as we know the process is empty.  We may change our mind later.
15427            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15428            // At this point we don't actually know the adjustment.  Use the cached adj
15429            // value that the caller wants us to.
15430            adj = cachedAdj;
15431            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15432            app.cached = true;
15433            app.empty = true;
15434            app.adjType = "cch-empty";
15435        }
15436
15437        // Examine all activities if not already foreground.
15438        if (!foregroundActivities && activitiesSize > 0) {
15439            for (int j = 0; j < activitiesSize; j++) {
15440                final ActivityRecord r = app.activities.get(j);
15441                if (r.app != app) {
15442                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
15443                            + app + "?!?");
15444                    continue;
15445                }
15446                if (r.visible) {
15447                    // App has a visible activity; only upgrade adjustment.
15448                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15449                        adj = ProcessList.VISIBLE_APP_ADJ;
15450                        app.adjType = "visible";
15451                    }
15452                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15453                        procState = ActivityManager.PROCESS_STATE_TOP;
15454                    }
15455                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15456                    app.cached = false;
15457                    app.empty = false;
15458                    foregroundActivities = true;
15459                    break;
15460                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
15461                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15462                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15463                        app.adjType = "pausing";
15464                    }
15465                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
15466                        procState = ActivityManager.PROCESS_STATE_TOP;
15467                    }
15468                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15469                    app.cached = false;
15470                    app.empty = false;
15471                    foregroundActivities = true;
15472                } else if (r.state == ActivityState.STOPPING) {
15473                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15474                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15475                        app.adjType = "stopping";
15476                    }
15477                    // For the process state, we will at this point consider the
15478                    // process to be cached.  It will be cached either as an activity
15479                    // or empty depending on whether the activity is finishing.  We do
15480                    // this so that we can treat the process as cached for purposes of
15481                    // memory trimming (determing current memory level, trim command to
15482                    // send to process) since there can be an arbitrary number of stopping
15483                    // processes and they should soon all go into the cached state.
15484                    if (!r.finishing) {
15485                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15486                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15487                        }
15488                    }
15489                    app.cached = false;
15490                    app.empty = false;
15491                    foregroundActivities = true;
15492                } else {
15493                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15494                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15495                        app.adjType = "cch-act";
15496                    }
15497                }
15498            }
15499        }
15500
15501        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15502            if (app.foregroundServices) {
15503                // The user is aware of this app, so make it visible.
15504                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15505                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15506                app.cached = false;
15507                app.adjType = "fg-service";
15508                schedGroup = Process.THREAD_GROUP_DEFAULT;
15509            } else if (app.forcingToForeground != null) {
15510                // The user is aware of this app, so make it visible.
15511                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15512                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15513                app.cached = false;
15514                app.adjType = "force-fg";
15515                app.adjSource = app.forcingToForeground;
15516                schedGroup = Process.THREAD_GROUP_DEFAULT;
15517            }
15518        }
15519
15520        if (app == mHeavyWeightProcess) {
15521            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
15522                // We don't want to kill the current heavy-weight process.
15523                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
15524                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15525                app.cached = false;
15526                app.adjType = "heavy";
15527            }
15528            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
15529                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
15530            }
15531        }
15532
15533        if (app == mHomeProcess) {
15534            if (adj > ProcessList.HOME_APP_ADJ) {
15535                // This process is hosting what we currently consider to be the
15536                // home app, so we don't want to let it go into the background.
15537                adj = ProcessList.HOME_APP_ADJ;
15538                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15539                app.cached = false;
15540                app.adjType = "home";
15541            }
15542            if (procState > ActivityManager.PROCESS_STATE_HOME) {
15543                procState = ActivityManager.PROCESS_STATE_HOME;
15544            }
15545        }
15546
15547        if (app == mPreviousProcess && app.activities.size() > 0) {
15548            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
15549                // This was the previous process that showed UI to the user.
15550                // We want to try to keep it around more aggressively, to give
15551                // a good experience around switching between two apps.
15552                adj = ProcessList.PREVIOUS_APP_ADJ;
15553                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
15554                app.cached = false;
15555                app.adjType = "previous";
15556            }
15557            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
15558                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
15559            }
15560        }
15561
15562        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
15563                + " reason=" + app.adjType);
15564
15565        // By default, we use the computed adjustment.  It may be changed if
15566        // there are applications dependent on our services or providers, but
15567        // this gives us a baseline and makes sure we don't get into an
15568        // infinite recursion.
15569        app.adjSeq = mAdjSeq;
15570        app.curRawAdj = adj;
15571        app.hasStartedServices = false;
15572
15573        if (mBackupTarget != null && app == mBackupTarget.app) {
15574            // If possible we want to avoid killing apps while they're being backed up
15575            if (adj > ProcessList.BACKUP_APP_ADJ) {
15576                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
15577                adj = ProcessList.BACKUP_APP_ADJ;
15578                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15579                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15580                }
15581                app.adjType = "backup";
15582                app.cached = false;
15583            }
15584            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
15585                procState = ActivityManager.PROCESS_STATE_BACKUP;
15586            }
15587        }
15588
15589        boolean mayBeTop = false;
15590
15591        for (int is = app.services.size()-1;
15592                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15593                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15594                        || procState > ActivityManager.PROCESS_STATE_TOP);
15595                is--) {
15596            ServiceRecord s = app.services.valueAt(is);
15597            if (s.startRequested) {
15598                app.hasStartedServices = true;
15599                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
15600                    procState = ActivityManager.PROCESS_STATE_SERVICE;
15601                }
15602                if (app.hasShownUi && app != mHomeProcess) {
15603                    // If this process has shown some UI, let it immediately
15604                    // go to the LRU list because it may be pretty heavy with
15605                    // UI stuff.  We'll tag it with a label just to help
15606                    // debug and understand what is going on.
15607                    if (adj > ProcessList.SERVICE_ADJ) {
15608                        app.adjType = "cch-started-ui-services";
15609                    }
15610                } else {
15611                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15612                        // This service has seen some activity within
15613                        // recent memory, so we will keep its process ahead
15614                        // of the background processes.
15615                        if (adj > ProcessList.SERVICE_ADJ) {
15616                            adj = ProcessList.SERVICE_ADJ;
15617                            app.adjType = "started-services";
15618                            app.cached = false;
15619                        }
15620                    }
15621                    // If we have let the service slide into the background
15622                    // state, still have some text describing what it is doing
15623                    // even though the service no longer has an impact.
15624                    if (adj > ProcessList.SERVICE_ADJ) {
15625                        app.adjType = "cch-started-services";
15626                    }
15627                }
15628            }
15629            for (int conni = s.connections.size()-1;
15630                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15631                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15632                            || procState > ActivityManager.PROCESS_STATE_TOP);
15633                    conni--) {
15634                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
15635                for (int i = 0;
15636                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
15637                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15638                                || procState > ActivityManager.PROCESS_STATE_TOP);
15639                        i++) {
15640                    // XXX should compute this based on the max of
15641                    // all connected clients.
15642                    ConnectionRecord cr = clist.get(i);
15643                    if (cr.binding.client == app) {
15644                        // Binding to ourself is not interesting.
15645                        continue;
15646                    }
15647                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
15648                        ProcessRecord client = cr.binding.client;
15649                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
15650                                TOP_APP, doingAll, now);
15651                        int clientProcState = client.curProcState;
15652                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15653                            // If the other app is cached for any reason, for purposes here
15654                            // we are going to consider it empty.  The specific cached state
15655                            // doesn't propagate except under certain conditions.
15656                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15657                        }
15658                        String adjType = null;
15659                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
15660                            // Not doing bind OOM management, so treat
15661                            // this guy more like a started service.
15662                            if (app.hasShownUi && app != mHomeProcess) {
15663                                // If this process has shown some UI, let it immediately
15664                                // go to the LRU list because it may be pretty heavy with
15665                                // UI stuff.  We'll tag it with a label just to help
15666                                // debug and understand what is going on.
15667                                if (adj > clientAdj) {
15668                                    adjType = "cch-bound-ui-services";
15669                                }
15670                                app.cached = false;
15671                                clientAdj = adj;
15672                                clientProcState = procState;
15673                            } else {
15674                                if (now >= (s.lastActivity
15675                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
15676                                    // This service has not seen activity within
15677                                    // recent memory, so allow it to drop to the
15678                                    // LRU list if there is no other reason to keep
15679                                    // it around.  We'll also tag it with a label just
15680                                    // to help debug and undertand what is going on.
15681                                    if (adj > clientAdj) {
15682                                        adjType = "cch-bound-services";
15683                                    }
15684                                    clientAdj = adj;
15685                                }
15686                            }
15687                        }
15688                        if (adj > clientAdj) {
15689                            // If this process has recently shown UI, and
15690                            // the process that is binding to it is less
15691                            // important than being visible, then we don't
15692                            // care about the binding as much as we care
15693                            // about letting this process get into the LRU
15694                            // list to be killed and restarted if needed for
15695                            // memory.
15696                            if (app.hasShownUi && app != mHomeProcess
15697                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15698                                adjType = "cch-bound-ui-services";
15699                            } else {
15700                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
15701                                        |Context.BIND_IMPORTANT)) != 0) {
15702                                    adj = clientAdj;
15703                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
15704                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
15705                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15706                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
15707                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
15708                                    adj = clientAdj;
15709                                } else {
15710                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
15711                                        adj = ProcessList.VISIBLE_APP_ADJ;
15712                                    }
15713                                }
15714                                if (!client.cached) {
15715                                    app.cached = false;
15716                                }
15717                                adjType = "service";
15718                            }
15719                        }
15720                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15721                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15722                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15723                            }
15724                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15725                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15726                                    // Special handling of clients who are in the top state.
15727                                    // We *may* want to consider this process to be in the
15728                                    // top state as well, but only if there is not another
15729                                    // reason for it to be running.  Being on the top is a
15730                                    // special state, meaning you are specifically running
15731                                    // for the current top app.  If the process is already
15732                                    // running in the background for some other reason, it
15733                                    // is more important to continue considering it to be
15734                                    // in the background state.
15735                                    mayBeTop = true;
15736                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15737                                } else {
15738                                    // Special handling for above-top states (persistent
15739                                    // processes).  These should not bring the current process
15740                                    // into the top state, since they are not on top.  Instead
15741                                    // give them the best state after that.
15742                                    clientProcState =
15743                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15744                                }
15745                            }
15746                        } else {
15747                            if (clientProcState <
15748                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
15749                                clientProcState =
15750                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
15751                            }
15752                        }
15753                        if (procState > clientProcState) {
15754                            procState = clientProcState;
15755                        }
15756                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
15757                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
15758                            app.pendingUiClean = true;
15759                        }
15760                        if (adjType != null) {
15761                            app.adjType = adjType;
15762                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15763                                    .REASON_SERVICE_IN_USE;
15764                            app.adjSource = cr.binding.client;
15765                            app.adjSourceProcState = clientProcState;
15766                            app.adjTarget = s.name;
15767                        }
15768                    }
15769                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
15770                        app.treatLikeActivity = true;
15771                    }
15772                    final ActivityRecord a = cr.activity;
15773                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
15774                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
15775                                (a.visible || a.state == ActivityState.RESUMED
15776                                 || a.state == ActivityState.PAUSING)) {
15777                            adj = ProcessList.FOREGROUND_APP_ADJ;
15778                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
15779                                schedGroup = Process.THREAD_GROUP_DEFAULT;
15780                            }
15781                            app.cached = false;
15782                            app.adjType = "service";
15783                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15784                                    .REASON_SERVICE_IN_USE;
15785                            app.adjSource = a;
15786                            app.adjSourceProcState = procState;
15787                            app.adjTarget = s.name;
15788                        }
15789                    }
15790                }
15791            }
15792        }
15793
15794        for (int provi = app.pubProviders.size()-1;
15795                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15796                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15797                        || procState > ActivityManager.PROCESS_STATE_TOP);
15798                provi--) {
15799            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
15800            for (int i = cpr.connections.size()-1;
15801                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
15802                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
15803                            || procState > ActivityManager.PROCESS_STATE_TOP);
15804                    i--) {
15805                ContentProviderConnection conn = cpr.connections.get(i);
15806                ProcessRecord client = conn.client;
15807                if (client == app) {
15808                    // Being our own client is not interesting.
15809                    continue;
15810                }
15811                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
15812                int clientProcState = client.curProcState;
15813                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
15814                    // If the other app is cached for any reason, for purposes here
15815                    // we are going to consider it empty.
15816                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15817                }
15818                if (adj > clientAdj) {
15819                    if (app.hasShownUi && app != mHomeProcess
15820                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
15821                        app.adjType = "cch-ui-provider";
15822                    } else {
15823                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
15824                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
15825                        app.adjType = "provider";
15826                    }
15827                    app.cached &= client.cached;
15828                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
15829                            .REASON_PROVIDER_IN_USE;
15830                    app.adjSource = client;
15831                    app.adjSourceProcState = clientProcState;
15832                    app.adjTarget = cpr.name;
15833                }
15834                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
15835                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
15836                        // Special handling of clients who are in the top state.
15837                        // We *may* want to consider this process to be in the
15838                        // top state as well, but only if there is not another
15839                        // reason for it to be running.  Being on the top is a
15840                        // special state, meaning you are specifically running
15841                        // for the current top app.  If the process is already
15842                        // running in the background for some other reason, it
15843                        // is more important to continue considering it to be
15844                        // in the background state.
15845                        mayBeTop = true;
15846                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
15847                    } else {
15848                        // Special handling for above-top states (persistent
15849                        // processes).  These should not bring the current process
15850                        // into the top state, since they are not on top.  Instead
15851                        // give them the best state after that.
15852                        clientProcState =
15853                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15854                    }
15855                }
15856                if (procState > clientProcState) {
15857                    procState = clientProcState;
15858                }
15859                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
15860                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15861                }
15862            }
15863            // If the provider has external (non-framework) process
15864            // dependencies, ensure that its adjustment is at least
15865            // FOREGROUND_APP_ADJ.
15866            if (cpr.hasExternalProcessHandles()) {
15867                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
15868                    adj = ProcessList.FOREGROUND_APP_ADJ;
15869                    schedGroup = Process.THREAD_GROUP_DEFAULT;
15870                    app.cached = false;
15871                    app.adjType = "provider";
15872                    app.adjTarget = cpr.name;
15873                }
15874                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
15875                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15876                }
15877            }
15878        }
15879
15880        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
15881            // A client of one of our services or providers is in the top state.  We
15882            // *may* want to be in the top state, but not if we are already running in
15883            // the background for some other reason.  For the decision here, we are going
15884            // to pick out a few specific states that we want to remain in when a client
15885            // is top (states that tend to be longer-term) and otherwise allow it to go
15886            // to the top state.
15887            switch (procState) {
15888                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
15889                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
15890                case ActivityManager.PROCESS_STATE_SERVICE:
15891                    // These all are longer-term states, so pull them up to the top
15892                    // of the background states, but not all the way to the top state.
15893                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
15894                    break;
15895                default:
15896                    // Otherwise, top is a better choice, so take it.
15897                    procState = ActivityManager.PROCESS_STATE_TOP;
15898                    break;
15899            }
15900        }
15901
15902        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
15903            if (app.hasClientActivities) {
15904                // This is a cached process, but with client activities.  Mark it so.
15905                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
15906                app.adjType = "cch-client-act";
15907            } else if (app.treatLikeActivity) {
15908                // This is a cached process, but somebody wants us to treat it like it has
15909                // an activity, okay!
15910                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
15911                app.adjType = "cch-as-act";
15912            }
15913        }
15914
15915        if (adj == ProcessList.SERVICE_ADJ) {
15916            if (doingAll) {
15917                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
15918                mNewNumServiceProcs++;
15919                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
15920                if (!app.serviceb) {
15921                    // This service isn't far enough down on the LRU list to
15922                    // normally be a B service, but if we are low on RAM and it
15923                    // is large we want to force it down since we would prefer to
15924                    // keep launcher over it.
15925                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
15926                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
15927                        app.serviceHighRam = true;
15928                        app.serviceb = true;
15929                        //Slog.i(TAG, "ADJ " + app + " high ram!");
15930                    } else {
15931                        mNewNumAServiceProcs++;
15932                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
15933                    }
15934                } else {
15935                    app.serviceHighRam = false;
15936                }
15937            }
15938            if (app.serviceb) {
15939                adj = ProcessList.SERVICE_B_ADJ;
15940            }
15941        }
15942
15943        app.curRawAdj = adj;
15944
15945        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
15946        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
15947        if (adj > app.maxAdj) {
15948            adj = app.maxAdj;
15949            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
15950                schedGroup = Process.THREAD_GROUP_DEFAULT;
15951            }
15952        }
15953
15954        // Do final modification to adj.  Everything we do between here and applying
15955        // the final setAdj must be done in this function, because we will also use
15956        // it when computing the final cached adj later.  Note that we don't need to
15957        // worry about this for max adj above, since max adj will always be used to
15958        // keep it out of the cached vaues.
15959        app.curAdj = app.modifyRawOomAdj(adj);
15960        app.curSchedGroup = schedGroup;
15961        app.curProcState = procState;
15962        app.foregroundActivities = foregroundActivities;
15963
15964        return app.curRawAdj;
15965    }
15966
15967    /**
15968     * Schedule PSS collection of a process.
15969     */
15970    void requestPssLocked(ProcessRecord proc, int procState) {
15971        if (mPendingPssProcesses.contains(proc)) {
15972            return;
15973        }
15974        if (mPendingPssProcesses.size() == 0) {
15975            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
15976        }
15977        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
15978        proc.pssProcState = procState;
15979        mPendingPssProcesses.add(proc);
15980    }
15981
15982    /**
15983     * Schedule PSS collection of all processes.
15984     */
15985    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
15986        if (!always) {
15987            if (now < (mLastFullPssTime +
15988                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
15989                return;
15990            }
15991        }
15992        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
15993        mLastFullPssTime = now;
15994        mFullPssPending = true;
15995        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
15996        mPendingPssProcesses.clear();
15997        for (int i=mLruProcesses.size()-1; i>=0; i--) {
15998            ProcessRecord app = mLruProcesses.get(i);
15999            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16000                app.pssProcState = app.setProcState;
16001                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16002                        isSleeping(), now);
16003                mPendingPssProcesses.add(app);
16004            }
16005        }
16006        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16007    }
16008
16009    /**
16010     * Ask a given process to GC right now.
16011     */
16012    final void performAppGcLocked(ProcessRecord app) {
16013        try {
16014            app.lastRequestedGc = SystemClock.uptimeMillis();
16015            if (app.thread != null) {
16016                if (app.reportLowMemory) {
16017                    app.reportLowMemory = false;
16018                    app.thread.scheduleLowMemory();
16019                } else {
16020                    app.thread.processInBackground();
16021                }
16022            }
16023        } catch (Exception e) {
16024            // whatever.
16025        }
16026    }
16027
16028    /**
16029     * Returns true if things are idle enough to perform GCs.
16030     */
16031    private final boolean canGcNowLocked() {
16032        boolean processingBroadcasts = false;
16033        for (BroadcastQueue q : mBroadcastQueues) {
16034            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16035                processingBroadcasts = true;
16036            }
16037        }
16038        return !processingBroadcasts
16039                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16040    }
16041
16042    /**
16043     * Perform GCs on all processes that are waiting for it, but only
16044     * if things are idle.
16045     */
16046    final void performAppGcsLocked() {
16047        final int N = mProcessesToGc.size();
16048        if (N <= 0) {
16049            return;
16050        }
16051        if (canGcNowLocked()) {
16052            while (mProcessesToGc.size() > 0) {
16053                ProcessRecord proc = mProcessesToGc.remove(0);
16054                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16055                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16056                            <= SystemClock.uptimeMillis()) {
16057                        // To avoid spamming the system, we will GC processes one
16058                        // at a time, waiting a few seconds between each.
16059                        performAppGcLocked(proc);
16060                        scheduleAppGcsLocked();
16061                        return;
16062                    } else {
16063                        // It hasn't been long enough since we last GCed this
16064                        // process...  put it in the list to wait for its time.
16065                        addProcessToGcListLocked(proc);
16066                        break;
16067                    }
16068                }
16069            }
16070
16071            scheduleAppGcsLocked();
16072        }
16073    }
16074
16075    /**
16076     * If all looks good, perform GCs on all processes waiting for them.
16077     */
16078    final void performAppGcsIfAppropriateLocked() {
16079        if (canGcNowLocked()) {
16080            performAppGcsLocked();
16081            return;
16082        }
16083        // Still not idle, wait some more.
16084        scheduleAppGcsLocked();
16085    }
16086
16087    /**
16088     * Schedule the execution of all pending app GCs.
16089     */
16090    final void scheduleAppGcsLocked() {
16091        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16092
16093        if (mProcessesToGc.size() > 0) {
16094            // Schedule a GC for the time to the next process.
16095            ProcessRecord proc = mProcessesToGc.get(0);
16096            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16097
16098            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16099            long now = SystemClock.uptimeMillis();
16100            if (when < (now+GC_TIMEOUT)) {
16101                when = now + GC_TIMEOUT;
16102            }
16103            mHandler.sendMessageAtTime(msg, when);
16104        }
16105    }
16106
16107    /**
16108     * Add a process to the array of processes waiting to be GCed.  Keeps the
16109     * list in sorted order by the last GC time.  The process can't already be
16110     * on the list.
16111     */
16112    final void addProcessToGcListLocked(ProcessRecord proc) {
16113        boolean added = false;
16114        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16115            if (mProcessesToGc.get(i).lastRequestedGc <
16116                    proc.lastRequestedGc) {
16117                added = true;
16118                mProcessesToGc.add(i+1, proc);
16119                break;
16120            }
16121        }
16122        if (!added) {
16123            mProcessesToGc.add(0, proc);
16124        }
16125    }
16126
16127    /**
16128     * Set up to ask a process to GC itself.  This will either do it
16129     * immediately, or put it on the list of processes to gc the next
16130     * time things are idle.
16131     */
16132    final void scheduleAppGcLocked(ProcessRecord app) {
16133        long now = SystemClock.uptimeMillis();
16134        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16135            return;
16136        }
16137        if (!mProcessesToGc.contains(app)) {
16138            addProcessToGcListLocked(app);
16139            scheduleAppGcsLocked();
16140        }
16141    }
16142
16143    final void checkExcessivePowerUsageLocked(boolean doKills) {
16144        updateCpuStatsNow();
16145
16146        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16147        boolean doWakeKills = doKills;
16148        boolean doCpuKills = doKills;
16149        if (mLastPowerCheckRealtime == 0) {
16150            doWakeKills = false;
16151        }
16152        if (mLastPowerCheckUptime == 0) {
16153            doCpuKills = false;
16154        }
16155        if (stats.isScreenOn()) {
16156            doWakeKills = false;
16157        }
16158        final long curRealtime = SystemClock.elapsedRealtime();
16159        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16160        final long curUptime = SystemClock.uptimeMillis();
16161        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16162        mLastPowerCheckRealtime = curRealtime;
16163        mLastPowerCheckUptime = curUptime;
16164        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16165            doWakeKills = false;
16166        }
16167        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16168            doCpuKills = false;
16169        }
16170        int i = mLruProcesses.size();
16171        while (i > 0) {
16172            i--;
16173            ProcessRecord app = mLruProcesses.get(i);
16174            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16175                long wtime;
16176                synchronized (stats) {
16177                    wtime = stats.getProcessWakeTime(app.info.uid,
16178                            app.pid, curRealtime);
16179                }
16180                long wtimeUsed = wtime - app.lastWakeTime;
16181                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16182                if (DEBUG_POWER) {
16183                    StringBuilder sb = new StringBuilder(128);
16184                    sb.append("Wake for ");
16185                    app.toShortString(sb);
16186                    sb.append(": over ");
16187                    TimeUtils.formatDuration(realtimeSince, sb);
16188                    sb.append(" used ");
16189                    TimeUtils.formatDuration(wtimeUsed, sb);
16190                    sb.append(" (");
16191                    sb.append((wtimeUsed*100)/realtimeSince);
16192                    sb.append("%)");
16193                    Slog.i(TAG, sb.toString());
16194                    sb.setLength(0);
16195                    sb.append("CPU for ");
16196                    app.toShortString(sb);
16197                    sb.append(": over ");
16198                    TimeUtils.formatDuration(uptimeSince, sb);
16199                    sb.append(" used ");
16200                    TimeUtils.formatDuration(cputimeUsed, sb);
16201                    sb.append(" (");
16202                    sb.append((cputimeUsed*100)/uptimeSince);
16203                    sb.append("%)");
16204                    Slog.i(TAG, sb.toString());
16205                }
16206                // If a process has held a wake lock for more
16207                // than 50% of the time during this period,
16208                // that sounds bad.  Kill!
16209                if (doWakeKills && realtimeSince > 0
16210                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16211                    synchronized (stats) {
16212                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16213                                realtimeSince, wtimeUsed);
16214                    }
16215                    killUnneededProcessLocked(app, "excessive wake held " + wtimeUsed
16216                            + " during " + realtimeSince);
16217                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16218                } else if (doCpuKills && uptimeSince > 0
16219                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16220                    synchronized (stats) {
16221                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16222                                uptimeSince, cputimeUsed);
16223                    }
16224                    killUnneededProcessLocked(app, "excessive cpu " + cputimeUsed
16225                            + " during " + uptimeSince);
16226                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16227                } else {
16228                    app.lastWakeTime = wtime;
16229                    app.lastCpuTime = app.curCpuTime;
16230                }
16231            }
16232        }
16233    }
16234
16235    private final boolean applyOomAdjLocked(ProcessRecord app,
16236            ProcessRecord TOP_APP, boolean doingAll, long now) {
16237        boolean success = true;
16238
16239        if (app.curRawAdj != app.setRawAdj) {
16240            app.setRawAdj = app.curRawAdj;
16241        }
16242
16243        int changes = 0;
16244
16245        if (app.curAdj != app.setAdj) {
16246            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16247            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16248                TAG, "Set " + app.pid + " " + app.processName +
16249                " adj " + app.curAdj + ": " + app.adjType);
16250            app.setAdj = app.curAdj;
16251        }
16252
16253        if (app.setSchedGroup != app.curSchedGroup) {
16254            app.setSchedGroup = app.curSchedGroup;
16255            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16256                    "Setting process group of " + app.processName
16257                    + " to " + app.curSchedGroup);
16258            if (app.waitingToKill != null &&
16259                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
16260                killUnneededProcessLocked(app, app.waitingToKill);
16261                success = false;
16262            } else {
16263                if (true) {
16264                    long oldId = Binder.clearCallingIdentity();
16265                    try {
16266                        Process.setProcessGroup(app.pid, app.curSchedGroup);
16267                    } catch (Exception e) {
16268                        Slog.w(TAG, "Failed setting process group of " + app.pid
16269                                + " to " + app.curSchedGroup);
16270                        e.printStackTrace();
16271                    } finally {
16272                        Binder.restoreCallingIdentity(oldId);
16273                    }
16274                } else {
16275                    if (app.thread != null) {
16276                        try {
16277                            app.thread.setSchedulingGroup(app.curSchedGroup);
16278                        } catch (RemoteException e) {
16279                        }
16280                    }
16281                }
16282                Process.setSwappiness(app.pid,
16283                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
16284            }
16285        }
16286        if (app.repForegroundActivities != app.foregroundActivities) {
16287            app.repForegroundActivities = app.foregroundActivities;
16288            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
16289        }
16290        if (app.repProcState != app.curProcState) {
16291            app.repProcState = app.curProcState;
16292            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
16293            if (app.thread != null) {
16294                try {
16295                    if (false) {
16296                        //RuntimeException h = new RuntimeException("here");
16297                        Slog.i(TAG, "Sending new process state " + app.repProcState
16298                                + " to " + app /*, h*/);
16299                    }
16300                    app.thread.setProcessState(app.repProcState);
16301                } catch (RemoteException e) {
16302                }
16303            }
16304        }
16305        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
16306                app.setProcState)) {
16307            app.lastStateTime = now;
16308            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16309                    isSleeping(), now);
16310            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
16311                    + ProcessList.makeProcStateString(app.setProcState) + " to "
16312                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
16313                    + (app.nextPssTime-now) + ": " + app);
16314        } else {
16315            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
16316                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
16317                requestPssLocked(app, app.setProcState);
16318                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
16319                        isSleeping(), now);
16320            } else if (false && DEBUG_PSS) {
16321                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
16322            }
16323        }
16324        if (app.setProcState != app.curProcState) {
16325            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16326                    "Proc state change of " + app.processName
16327                    + " to " + app.curProcState);
16328            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
16329            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
16330            if (setImportant && !curImportant) {
16331                // This app is no longer something we consider important enough to allow to
16332                // use arbitrary amounts of battery power.  Note
16333                // its current wake lock time to later know to kill it if
16334                // it is not behaving well.
16335                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16336                synchronized (stats) {
16337                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
16338                            app.pid, SystemClock.elapsedRealtime());
16339                }
16340                app.lastCpuTime = app.curCpuTime;
16341
16342            }
16343            app.setProcState = app.curProcState;
16344            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16345                app.notCachedSinceIdle = false;
16346            }
16347            if (!doingAll) {
16348                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
16349            } else {
16350                app.procStateChanged = true;
16351            }
16352        }
16353
16354        if (changes != 0) {
16355            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
16356            int i = mPendingProcessChanges.size()-1;
16357            ProcessChangeItem item = null;
16358            while (i >= 0) {
16359                item = mPendingProcessChanges.get(i);
16360                if (item.pid == app.pid) {
16361                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
16362                    break;
16363                }
16364                i--;
16365            }
16366            if (i < 0) {
16367                // No existing item in pending changes; need a new one.
16368                final int NA = mAvailProcessChanges.size();
16369                if (NA > 0) {
16370                    item = mAvailProcessChanges.remove(NA-1);
16371                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
16372                } else {
16373                    item = new ProcessChangeItem();
16374                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
16375                }
16376                item.changes = 0;
16377                item.pid = app.pid;
16378                item.uid = app.info.uid;
16379                if (mPendingProcessChanges.size() == 0) {
16380                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
16381                            "*** Enqueueing dispatch processes changed!");
16382                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
16383                }
16384                mPendingProcessChanges.add(item);
16385            }
16386            item.changes |= changes;
16387            item.processState = app.repProcState;
16388            item.foregroundActivities = app.repForegroundActivities;
16389            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
16390                    + Integer.toHexString(System.identityHashCode(item))
16391                    + " " + app.toShortString() + ": changes=" + item.changes
16392                    + " procState=" + item.processState
16393                    + " foreground=" + item.foregroundActivities
16394                    + " type=" + app.adjType + " source=" + app.adjSource
16395                    + " target=" + app.adjTarget);
16396        }
16397
16398        return success;
16399    }
16400
16401    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
16402        if (proc.thread != null) {
16403            if (proc.baseProcessTracker != null) {
16404                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
16405            }
16406            if (proc.repProcState >= 0) {
16407                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
16408                        proc.repProcState);
16409            }
16410        }
16411    }
16412
16413    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
16414            ProcessRecord TOP_APP, boolean doingAll, long now) {
16415        if (app.thread == null) {
16416            return false;
16417        }
16418
16419        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
16420
16421        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
16422    }
16423
16424    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
16425            boolean oomAdj) {
16426        if (isForeground != proc.foregroundServices) {
16427            proc.foregroundServices = isForeground;
16428            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
16429                    proc.info.uid);
16430            if (isForeground) {
16431                if (curProcs == null) {
16432                    curProcs = new ArrayList<ProcessRecord>();
16433                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
16434                }
16435                if (!curProcs.contains(proc)) {
16436                    curProcs.add(proc);
16437                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
16438                            proc.info.packageName, proc.info.uid);
16439                }
16440            } else {
16441                if (curProcs != null) {
16442                    if (curProcs.remove(proc)) {
16443                        mBatteryStatsService.noteEvent(
16444                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
16445                                proc.info.packageName, proc.info.uid);
16446                        if (curProcs.size() <= 0) {
16447                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
16448                        }
16449                    }
16450                }
16451            }
16452            if (oomAdj) {
16453                updateOomAdjLocked();
16454            }
16455        }
16456    }
16457
16458    private final ActivityRecord resumedAppLocked() {
16459        ActivityRecord act = mStackSupervisor.resumedAppLocked();
16460        String pkg;
16461        int uid;
16462        if (act != null) {
16463            pkg = act.packageName;
16464            uid = act.info.applicationInfo.uid;
16465        } else {
16466            pkg = null;
16467            uid = -1;
16468        }
16469        // Has the UID or resumed package name changed?
16470        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
16471                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
16472            if (mCurResumedPackage != null) {
16473                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
16474                        mCurResumedPackage, mCurResumedUid);
16475            }
16476            mCurResumedPackage = pkg;
16477            mCurResumedUid = uid;
16478            if (mCurResumedPackage != null) {
16479                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
16480                        mCurResumedPackage, mCurResumedUid);
16481            }
16482        }
16483        return act;
16484    }
16485
16486    final boolean updateOomAdjLocked(ProcessRecord app) {
16487        final ActivityRecord TOP_ACT = resumedAppLocked();
16488        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16489        final boolean wasCached = app.cached;
16490
16491        mAdjSeq++;
16492
16493        // This is the desired cached adjusment we want to tell it to use.
16494        // If our app is currently cached, we know it, and that is it.  Otherwise,
16495        // we don't know it yet, and it needs to now be cached we will then
16496        // need to do a complete oom adj.
16497        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
16498                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
16499        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
16500                SystemClock.uptimeMillis());
16501        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
16502            // Changed to/from cached state, so apps after it in the LRU
16503            // list may also be changed.
16504            updateOomAdjLocked();
16505        }
16506        return success;
16507    }
16508
16509    final void updateOomAdjLocked() {
16510        final ActivityRecord TOP_ACT = resumedAppLocked();
16511        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
16512        final long now = SystemClock.uptimeMillis();
16513        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
16514        final int N = mLruProcesses.size();
16515
16516        if (false) {
16517            RuntimeException e = new RuntimeException();
16518            e.fillInStackTrace();
16519            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
16520        }
16521
16522        mAdjSeq++;
16523        mNewNumServiceProcs = 0;
16524        mNewNumAServiceProcs = 0;
16525
16526        final int emptyProcessLimit;
16527        final int cachedProcessLimit;
16528        if (mProcessLimit <= 0) {
16529            emptyProcessLimit = cachedProcessLimit = 0;
16530        } else if (mProcessLimit == 1) {
16531            emptyProcessLimit = 1;
16532            cachedProcessLimit = 0;
16533        } else {
16534            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
16535            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
16536        }
16537
16538        // Let's determine how many processes we have running vs.
16539        // how many slots we have for background processes; we may want
16540        // to put multiple processes in a slot of there are enough of
16541        // them.
16542        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
16543                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
16544        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
16545        if (numEmptyProcs > cachedProcessLimit) {
16546            // If there are more empty processes than our limit on cached
16547            // processes, then use the cached process limit for the factor.
16548            // This ensures that the really old empty processes get pushed
16549            // down to the bottom, so if we are running low on memory we will
16550            // have a better chance at keeping around more cached processes
16551            // instead of a gazillion empty processes.
16552            numEmptyProcs = cachedProcessLimit;
16553        }
16554        int emptyFactor = numEmptyProcs/numSlots;
16555        if (emptyFactor < 1) emptyFactor = 1;
16556        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
16557        if (cachedFactor < 1) cachedFactor = 1;
16558        int stepCached = 0;
16559        int stepEmpty = 0;
16560        int numCached = 0;
16561        int numEmpty = 0;
16562        int numTrimming = 0;
16563
16564        mNumNonCachedProcs = 0;
16565        mNumCachedHiddenProcs = 0;
16566
16567        // First update the OOM adjustment for each of the
16568        // application processes based on their current state.
16569        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
16570        int nextCachedAdj = curCachedAdj+1;
16571        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
16572        int nextEmptyAdj = curEmptyAdj+2;
16573        for (int i=N-1; i>=0; i--) {
16574            ProcessRecord app = mLruProcesses.get(i);
16575            if (!app.killedByAm && app.thread != null) {
16576                app.procStateChanged = false;
16577                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
16578
16579                // If we haven't yet assigned the final cached adj
16580                // to the process, do that now.
16581                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
16582                    switch (app.curProcState) {
16583                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16584                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16585                            // This process is a cached process holding activities...
16586                            // assign it the next cached value for that type, and then
16587                            // step that cached level.
16588                            app.curRawAdj = curCachedAdj;
16589                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
16590                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
16591                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
16592                                    + ")");
16593                            if (curCachedAdj != nextCachedAdj) {
16594                                stepCached++;
16595                                if (stepCached >= cachedFactor) {
16596                                    stepCached = 0;
16597                                    curCachedAdj = nextCachedAdj;
16598                                    nextCachedAdj += 2;
16599                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16600                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
16601                                    }
16602                                }
16603                            }
16604                            break;
16605                        default:
16606                            // For everything else, assign next empty cached process
16607                            // level and bump that up.  Note that this means that
16608                            // long-running services that have dropped down to the
16609                            // cached level will be treated as empty (since their process
16610                            // state is still as a service), which is what we want.
16611                            app.curRawAdj = curEmptyAdj;
16612                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
16613                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
16614                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
16615                                    + ")");
16616                            if (curEmptyAdj != nextEmptyAdj) {
16617                                stepEmpty++;
16618                                if (stepEmpty >= emptyFactor) {
16619                                    stepEmpty = 0;
16620                                    curEmptyAdj = nextEmptyAdj;
16621                                    nextEmptyAdj += 2;
16622                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
16623                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
16624                                    }
16625                                }
16626                            }
16627                            break;
16628                    }
16629                }
16630
16631                applyOomAdjLocked(app, TOP_APP, true, now);
16632
16633                // Count the number of process types.
16634                switch (app.curProcState) {
16635                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
16636                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
16637                        mNumCachedHiddenProcs++;
16638                        numCached++;
16639                        if (numCached > cachedProcessLimit) {
16640                            killUnneededProcessLocked(app, "cached #" + numCached);
16641                        }
16642                        break;
16643                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
16644                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
16645                                && app.lastActivityTime < oldTime) {
16646                            killUnneededProcessLocked(app, "empty for "
16647                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
16648                                    / 1000) + "s");
16649                        } else {
16650                            numEmpty++;
16651                            if (numEmpty > emptyProcessLimit) {
16652                                killUnneededProcessLocked(app, "empty #" + numEmpty);
16653                            }
16654                        }
16655                        break;
16656                    default:
16657                        mNumNonCachedProcs++;
16658                        break;
16659                }
16660
16661                if (app.isolated && app.services.size() <= 0) {
16662                    // If this is an isolated process, and there are no
16663                    // services running in it, then the process is no longer
16664                    // needed.  We agressively kill these because we can by
16665                    // definition not re-use the same process again, and it is
16666                    // good to avoid having whatever code was running in them
16667                    // left sitting around after no longer needed.
16668                    killUnneededProcessLocked(app, "isolated not needed");
16669                }
16670
16671                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16672                        && !app.killedByAm) {
16673                    numTrimming++;
16674                }
16675            }
16676        }
16677
16678        mNumServiceProcs = mNewNumServiceProcs;
16679
16680        // Now determine the memory trimming level of background processes.
16681        // Unfortunately we need to start at the back of the list to do this
16682        // properly.  We only do this if the number of background apps we
16683        // are managing to keep around is less than half the maximum we desire;
16684        // if we are keeping a good number around, we'll let them use whatever
16685        // memory they want.
16686        final int numCachedAndEmpty = numCached + numEmpty;
16687        int memFactor;
16688        if (numCached <= ProcessList.TRIM_CACHED_APPS
16689                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
16690            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
16691                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
16692            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
16693                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
16694            } else {
16695                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
16696            }
16697        } else {
16698            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
16699        }
16700        // We always allow the memory level to go up (better).  We only allow it to go
16701        // down if we are in a state where that is allowed, *and* the total number of processes
16702        // has gone down since last time.
16703        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
16704                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
16705                + " last=" + mLastNumProcesses);
16706        if (memFactor > mLastMemoryLevel) {
16707            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
16708                memFactor = mLastMemoryLevel;
16709                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
16710            }
16711        }
16712        mLastMemoryLevel = memFactor;
16713        mLastNumProcesses = mLruProcesses.size();
16714        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
16715        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
16716        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
16717            if (mLowRamStartTime == 0) {
16718                mLowRamStartTime = now;
16719            }
16720            int step = 0;
16721            int fgTrimLevel;
16722            switch (memFactor) {
16723                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16724                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
16725                    break;
16726                case ProcessStats.ADJ_MEM_FACTOR_LOW:
16727                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
16728                    break;
16729                default:
16730                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
16731                    break;
16732            }
16733            int factor = numTrimming/3;
16734            int minFactor = 2;
16735            if (mHomeProcess != null) minFactor++;
16736            if (mPreviousProcess != null) minFactor++;
16737            if (factor < minFactor) factor = minFactor;
16738            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
16739            for (int i=N-1; i>=0; i--) {
16740                ProcessRecord app = mLruProcesses.get(i);
16741                if (allChanged || app.procStateChanged) {
16742                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16743                    app.procStateChanged = false;
16744                }
16745                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
16746                        && !app.killedByAm) {
16747                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
16748                        try {
16749                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16750                                    "Trimming memory of " + app.processName
16751                                    + " to " + curLevel);
16752                            app.thread.scheduleTrimMemory(curLevel);
16753                        } catch (RemoteException e) {
16754                        }
16755                        if (false) {
16756                            // For now we won't do this; our memory trimming seems
16757                            // to be good enough at this point that destroying
16758                            // activities causes more harm than good.
16759                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
16760                                    && app != mHomeProcess && app != mPreviousProcess) {
16761                                // Need to do this on its own message because the stack may not
16762                                // be in a consistent state at this point.
16763                                // For these apps we will also finish their activities
16764                                // to help them free memory.
16765                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
16766                            }
16767                        }
16768                    }
16769                    app.trimMemoryLevel = curLevel;
16770                    step++;
16771                    if (step >= factor) {
16772                        step = 0;
16773                        switch (curLevel) {
16774                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
16775                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
16776                                break;
16777                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
16778                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16779                                break;
16780                        }
16781                    }
16782                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16783                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
16784                            && app.thread != null) {
16785                        try {
16786                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16787                                    "Trimming memory of heavy-weight " + app.processName
16788                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16789                            app.thread.scheduleTrimMemory(
16790                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
16791                        } catch (RemoteException e) {
16792                        }
16793                    }
16794                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
16795                } else {
16796                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16797                            || app.systemNoUi) && app.pendingUiClean) {
16798                        // If this application is now in the background and it
16799                        // had done UI, then give it the special trim level to
16800                        // have it free UI resources.
16801                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
16802                        if (app.trimMemoryLevel < level && app.thread != null) {
16803                            try {
16804                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16805                                        "Trimming memory of bg-ui " + app.processName
16806                                        + " to " + level);
16807                                app.thread.scheduleTrimMemory(level);
16808                            } catch (RemoteException e) {
16809                            }
16810                        }
16811                        app.pendingUiClean = false;
16812                    }
16813                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
16814                        try {
16815                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16816                                    "Trimming memory of fg " + app.processName
16817                                    + " to " + fgTrimLevel);
16818                            app.thread.scheduleTrimMemory(fgTrimLevel);
16819                        } catch (RemoteException e) {
16820                        }
16821                    }
16822                    app.trimMemoryLevel = fgTrimLevel;
16823                }
16824            }
16825        } else {
16826            if (mLowRamStartTime != 0) {
16827                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
16828                mLowRamStartTime = 0;
16829            }
16830            for (int i=N-1; i>=0; i--) {
16831                ProcessRecord app = mLruProcesses.get(i);
16832                if (allChanged || app.procStateChanged) {
16833                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
16834                    app.procStateChanged = false;
16835                }
16836                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16837                        || app.systemNoUi) && app.pendingUiClean) {
16838                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
16839                            && app.thread != null) {
16840                        try {
16841                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16842                                    "Trimming memory of ui hidden " + app.processName
16843                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16844                            app.thread.scheduleTrimMemory(
16845                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
16846                        } catch (RemoteException e) {
16847                        }
16848                    }
16849                    app.pendingUiClean = false;
16850                }
16851                app.trimMemoryLevel = 0;
16852            }
16853        }
16854
16855        if (mAlwaysFinishActivities) {
16856            // Need to do this on its own message because the stack may not
16857            // be in a consistent state at this point.
16858            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
16859        }
16860
16861        if (allChanged) {
16862            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
16863        }
16864
16865        if (mProcessStats.shouldWriteNowLocked(now)) {
16866            mHandler.post(new Runnable() {
16867                @Override public void run() {
16868                    synchronized (ActivityManagerService.this) {
16869                        mProcessStats.writeStateAsyncLocked();
16870                    }
16871                }
16872            });
16873        }
16874
16875        if (DEBUG_OOM_ADJ) {
16876            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
16877        }
16878    }
16879
16880    final void trimApplications() {
16881        synchronized (this) {
16882            int i;
16883
16884            // First remove any unused application processes whose package
16885            // has been removed.
16886            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
16887                final ProcessRecord app = mRemovedProcesses.get(i);
16888                if (app.activities.size() == 0
16889                        && app.curReceiver == null && app.services.size() == 0) {
16890                    Slog.i(
16891                        TAG, "Exiting empty application process "
16892                        + app.processName + " ("
16893                        + (app.thread != null ? app.thread.asBinder() : null)
16894                        + ")\n");
16895                    if (app.pid > 0 && app.pid != MY_PID) {
16896                        EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
16897                                app.processName, app.setAdj, "empty");
16898                        app.killedByAm = true;
16899                        Process.killProcessQuiet(app.pid);
16900                        Process.killProcessGroup(app.info.uid, app.pid);
16901                    } else {
16902                        try {
16903                            app.thread.scheduleExit();
16904                        } catch (Exception e) {
16905                            // Ignore exceptions.
16906                        }
16907                    }
16908                    cleanUpApplicationRecordLocked(app, false, true, -1);
16909                    mRemovedProcesses.remove(i);
16910
16911                    if (app.persistent) {
16912                        addAppLocked(app.info, false, null /* ABI override */);
16913                    }
16914                }
16915            }
16916
16917            // Now update the oom adj for all processes.
16918            updateOomAdjLocked();
16919        }
16920    }
16921
16922    /** This method sends the specified signal to each of the persistent apps */
16923    public void signalPersistentProcesses(int sig) throws RemoteException {
16924        if (sig != Process.SIGNAL_USR1) {
16925            throw new SecurityException("Only SIGNAL_USR1 is allowed");
16926        }
16927
16928        synchronized (this) {
16929            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
16930                    != PackageManager.PERMISSION_GRANTED) {
16931                throw new SecurityException("Requires permission "
16932                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
16933            }
16934
16935            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
16936                ProcessRecord r = mLruProcesses.get(i);
16937                if (r.thread != null && r.persistent) {
16938                    Process.sendSignal(r.pid, sig);
16939                }
16940            }
16941        }
16942    }
16943
16944    private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
16945        if (proc == null || proc == mProfileProc) {
16946            proc = mProfileProc;
16947            path = mProfileFile;
16948            profileType = mProfileType;
16949            clearProfilerLocked();
16950        }
16951        if (proc == null) {
16952            return;
16953        }
16954        try {
16955            proc.thread.profilerControl(false, path, null, profileType);
16956        } catch (RemoteException e) {
16957            throw new IllegalStateException("Process disappeared");
16958        }
16959    }
16960
16961    private void clearProfilerLocked() {
16962        if (mProfileFd != null) {
16963            try {
16964                mProfileFd.close();
16965            } catch (IOException e) {
16966            }
16967        }
16968        mProfileApp = null;
16969        mProfileProc = null;
16970        mProfileFile = null;
16971        mProfileType = 0;
16972        mAutoStopProfiler = false;
16973    }
16974
16975    public boolean profileControl(String process, int userId, boolean start,
16976            String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
16977
16978        try {
16979            synchronized (this) {
16980                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
16981                // its own permission.
16982                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
16983                        != PackageManager.PERMISSION_GRANTED) {
16984                    throw new SecurityException("Requires permission "
16985                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
16986                }
16987
16988                if (start && fd == null) {
16989                    throw new IllegalArgumentException("null fd");
16990                }
16991
16992                ProcessRecord proc = null;
16993                if (process != null) {
16994                    proc = findProcessLocked(process, userId, "profileControl");
16995                }
16996
16997                if (start && (proc == null || proc.thread == null)) {
16998                    throw new IllegalArgumentException("Unknown process: " + process);
16999                }
17000
17001                if (start) {
17002                    stopProfilerLocked(null, null, 0);
17003                    setProfileApp(proc.info, proc.processName, path, fd, false);
17004                    mProfileProc = proc;
17005                    mProfileType = profileType;
17006                    try {
17007                        fd = fd.dup();
17008                    } catch (IOException e) {
17009                        fd = null;
17010                    }
17011                    proc.thread.profilerControl(start, path, fd, profileType);
17012                    fd = null;
17013                    mProfileFd = null;
17014                } else {
17015                    stopProfilerLocked(proc, path, profileType);
17016                    if (fd != null) {
17017                        try {
17018                            fd.close();
17019                        } catch (IOException e) {
17020                        }
17021                    }
17022                }
17023
17024                return true;
17025            }
17026        } catch (RemoteException e) {
17027            throw new IllegalStateException("Process disappeared");
17028        } finally {
17029            if (fd != null) {
17030                try {
17031                    fd.close();
17032                } catch (IOException e) {
17033                }
17034            }
17035        }
17036    }
17037
17038    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17039        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17040                userId, true, ALLOW_FULL_ONLY, callName, null);
17041        ProcessRecord proc = null;
17042        try {
17043            int pid = Integer.parseInt(process);
17044            synchronized (mPidsSelfLocked) {
17045                proc = mPidsSelfLocked.get(pid);
17046            }
17047        } catch (NumberFormatException e) {
17048        }
17049
17050        if (proc == null) {
17051            ArrayMap<String, SparseArray<ProcessRecord>> all
17052                    = mProcessNames.getMap();
17053            SparseArray<ProcessRecord> procs = all.get(process);
17054            if (procs != null && procs.size() > 0) {
17055                proc = procs.valueAt(0);
17056                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17057                    for (int i=1; i<procs.size(); i++) {
17058                        ProcessRecord thisProc = procs.valueAt(i);
17059                        if (thisProc.userId == userId) {
17060                            proc = thisProc;
17061                            break;
17062                        }
17063                    }
17064                }
17065            }
17066        }
17067
17068        return proc;
17069    }
17070
17071    public boolean dumpHeap(String process, int userId, boolean managed,
17072            String path, ParcelFileDescriptor fd) throws RemoteException {
17073
17074        try {
17075            synchronized (this) {
17076                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17077                // its own permission (same as profileControl).
17078                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17079                        != PackageManager.PERMISSION_GRANTED) {
17080                    throw new SecurityException("Requires permission "
17081                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17082                }
17083
17084                if (fd == null) {
17085                    throw new IllegalArgumentException("null fd");
17086                }
17087
17088                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17089                if (proc == null || proc.thread == null) {
17090                    throw new IllegalArgumentException("Unknown process: " + process);
17091                }
17092
17093                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17094                if (!isDebuggable) {
17095                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17096                        throw new SecurityException("Process not debuggable: " + proc);
17097                    }
17098                }
17099
17100                proc.thread.dumpHeap(managed, path, fd);
17101                fd = null;
17102                return true;
17103            }
17104        } catch (RemoteException e) {
17105            throw new IllegalStateException("Process disappeared");
17106        } finally {
17107            if (fd != null) {
17108                try {
17109                    fd.close();
17110                } catch (IOException e) {
17111                }
17112            }
17113        }
17114    }
17115
17116    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17117    public void monitor() {
17118        synchronized (this) { }
17119    }
17120
17121    void onCoreSettingsChange(Bundle settings) {
17122        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17123            ProcessRecord processRecord = mLruProcesses.get(i);
17124            try {
17125                if (processRecord.thread != null) {
17126                    processRecord.thread.setCoreSettings(settings);
17127                }
17128            } catch (RemoteException re) {
17129                /* ignore */
17130            }
17131        }
17132    }
17133
17134    // Multi-user methods
17135
17136    /**
17137     * Start user, if its not already running, but don't bring it to foreground.
17138     */
17139    @Override
17140    public boolean startUserInBackground(final int userId) {
17141        return startUser(userId, /* foreground */ false);
17142    }
17143
17144    /**
17145     * Refreshes the list of users related to the current user when either a
17146     * user switch happens or when a new related user is started in the
17147     * background.
17148     */
17149    private void updateCurrentProfileIdsLocked() {
17150        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17151                mCurrentUserId, false /* enabledOnly */);
17152        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17153        for (int i = 0; i < currentProfileIds.length; i++) {
17154            currentProfileIds[i] = profiles.get(i).id;
17155        }
17156        mCurrentProfileIds = currentProfileIds;
17157
17158        synchronized (mUserProfileGroupIdsSelfLocked) {
17159            mUserProfileGroupIdsSelfLocked.clear();
17160            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17161            for (int i = 0; i < users.size(); i++) {
17162                UserInfo user = users.get(i);
17163                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17164                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17165                }
17166            }
17167        }
17168    }
17169
17170    private Set getProfileIdsLocked(int userId) {
17171        Set userIds = new HashSet<Integer>();
17172        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17173                userId, false /* enabledOnly */);
17174        for (UserInfo user : profiles) {
17175            userIds.add(Integer.valueOf(user.id));
17176        }
17177        return userIds;
17178    }
17179
17180    @Override
17181    public boolean switchUser(final int userId) {
17182        return startUser(userId, /* foregound */ true);
17183    }
17184
17185    private boolean startUser(final int userId, boolean foreground) {
17186        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17187                != PackageManager.PERMISSION_GRANTED) {
17188            String msg = "Permission Denial: switchUser() from pid="
17189                    + Binder.getCallingPid()
17190                    + ", uid=" + Binder.getCallingUid()
17191                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17192            Slog.w(TAG, msg);
17193            throw new SecurityException(msg);
17194        }
17195
17196        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17197
17198        final long ident = Binder.clearCallingIdentity();
17199        try {
17200            synchronized (this) {
17201                final int oldUserId = mCurrentUserId;
17202                if (oldUserId == userId) {
17203                    return true;
17204                }
17205
17206                mStackSupervisor.setLockTaskModeLocked(null, false);
17207
17208                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17209                if (userInfo == null) {
17210                    Slog.w(TAG, "No user info for user #" + userId);
17211                    return false;
17212                }
17213
17214                if (foreground) {
17215                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17216                            R.anim.screen_user_enter);
17217                }
17218
17219                boolean needStart = false;
17220
17221                // If the user we are switching to is not currently started, then
17222                // we need to start it now.
17223                if (mStartedUsers.get(userId) == null) {
17224                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17225                    updateStartedUserArrayLocked();
17226                    needStart = true;
17227                }
17228
17229                final Integer userIdInt = Integer.valueOf(userId);
17230                mUserLru.remove(userIdInt);
17231                mUserLru.add(userIdInt);
17232
17233                if (foreground) {
17234                    mCurrentUserId = userId;
17235                    updateCurrentProfileIdsLocked();
17236                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
17237                    // Once the internal notion of the active user has switched, we lock the device
17238                    // with the option to show the user switcher on the keyguard.
17239                    mWindowManager.lockNow(null);
17240                } else {
17241                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
17242                    updateCurrentProfileIdsLocked();
17243                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
17244                    mUserLru.remove(currentUserIdInt);
17245                    mUserLru.add(currentUserIdInt);
17246                }
17247
17248                final UserStartedState uss = mStartedUsers.get(userId);
17249
17250                // Make sure user is in the started state.  If it is currently
17251                // stopping, we need to knock that off.
17252                if (uss.mState == UserStartedState.STATE_STOPPING) {
17253                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
17254                    // so we can just fairly silently bring the user back from
17255                    // the almost-dead.
17256                    uss.mState = UserStartedState.STATE_RUNNING;
17257                    updateStartedUserArrayLocked();
17258                    needStart = true;
17259                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
17260                    // This means ACTION_SHUTDOWN has been sent, so we will
17261                    // need to treat this as a new boot of the user.
17262                    uss.mState = UserStartedState.STATE_BOOTING;
17263                    updateStartedUserArrayLocked();
17264                    needStart = true;
17265                }
17266
17267                if (uss.mState == UserStartedState.STATE_BOOTING) {
17268                    // Booting up a new user, need to tell system services about it.
17269                    // Note that this is on the same handler as scheduling of broadcasts,
17270                    // which is important because it needs to go first.
17271                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId));
17272                }
17273
17274                if (foreground) {
17275                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
17276                            oldUserId));
17277                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
17278                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17279                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
17280                            oldUserId, userId, uss));
17281                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
17282                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
17283                }
17284
17285                if (needStart) {
17286                    // Send USER_STARTED broadcast
17287                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
17288                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17289                            | Intent.FLAG_RECEIVER_FOREGROUND);
17290                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17291                    broadcastIntentLocked(null, null, intent,
17292                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17293                            false, false, MY_PID, Process.SYSTEM_UID, userId);
17294                }
17295
17296                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
17297                    if (userId != UserHandle.USER_OWNER) {
17298                        // Send PRE_BOOT_COMPLETED broadcasts for this new user
17299                        final ArrayList<ComponentName> doneReceivers
17300                                = new ArrayList<ComponentName>();
17301                        deliverPreBootCompleted(null, doneReceivers, userId);
17302
17303                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
17304                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
17305                        broadcastIntentLocked(null, null, intent, null,
17306                                new IIntentReceiver.Stub() {
17307                                    public void performReceive(Intent intent, int resultCode,
17308                                            String data, Bundle extras, boolean ordered,
17309                                            boolean sticky, int sendingUser) {
17310                                        userInitialized(uss, userId);
17311                                    }
17312                                }, 0, null, null, null, AppOpsManager.OP_NONE,
17313                                true, false, MY_PID, Process.SYSTEM_UID,
17314                                userId);
17315                        uss.initializing = true;
17316                    } else {
17317                        getUserManagerLocked().makeInitialized(userInfo.id);
17318                    }
17319                }
17320
17321                if (foreground) {
17322                    boolean homeInFront = mStackSupervisor.switchUserLocked(userId, uss);
17323                    if (homeInFront) {
17324                        startHomeActivityLocked(userId);
17325                    } else {
17326                        mStackSupervisor.resumeTopActivitiesLocked();
17327                    }
17328                    EventLogTags.writeAmSwitchUser(userId);
17329                    getUserManagerLocked().userForeground(userId);
17330                    sendUserSwitchBroadcastsLocked(oldUserId, userId);
17331                } else {
17332                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
17333                }
17334
17335                if (needStart) {
17336                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
17337                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17338                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17339                    broadcastIntentLocked(null, null, intent,
17340                            null, new IIntentReceiver.Stub() {
17341                                @Override
17342                                public void performReceive(Intent intent, int resultCode, String data,
17343                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
17344                                        throws RemoteException {
17345                                }
17346                            }, 0, null, null,
17347                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17348                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17349                }
17350            }
17351        } finally {
17352            Binder.restoreCallingIdentity(ident);
17353        }
17354
17355        return true;
17356    }
17357
17358    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
17359        long ident = Binder.clearCallingIdentity();
17360        try {
17361            Intent intent;
17362            if (oldUserId >= 0) {
17363                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
17364                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
17365                int count = profiles.size();
17366                for (int i = 0; i < count; i++) {
17367                    int profileUserId = profiles.get(i).id;
17368                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
17369                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17370                            | Intent.FLAG_RECEIVER_FOREGROUND);
17371                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17372                    broadcastIntentLocked(null, null, intent,
17373                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17374                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17375                }
17376            }
17377            if (newUserId >= 0) {
17378                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
17379                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
17380                int count = profiles.size();
17381                for (int i = 0; i < count; i++) {
17382                    int profileUserId = profiles.get(i).id;
17383                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
17384                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17385                            | Intent.FLAG_RECEIVER_FOREGROUND);
17386                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
17387                    broadcastIntentLocked(null, null, intent,
17388                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
17389                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
17390                }
17391                intent = new Intent(Intent.ACTION_USER_SWITCHED);
17392                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
17393                        | Intent.FLAG_RECEIVER_FOREGROUND);
17394                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
17395                broadcastIntentLocked(null, null, intent,
17396                        null, null, 0, null, null,
17397                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
17398                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17399            }
17400        } finally {
17401            Binder.restoreCallingIdentity(ident);
17402        }
17403    }
17404
17405    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
17406            final int newUserId) {
17407        final int N = mUserSwitchObservers.beginBroadcast();
17408        if (N > 0) {
17409            final IRemoteCallback callback = new IRemoteCallback.Stub() {
17410                int mCount = 0;
17411                @Override
17412                public void sendResult(Bundle data) throws RemoteException {
17413                    synchronized (ActivityManagerService.this) {
17414                        if (mCurUserSwitchCallback == this) {
17415                            mCount++;
17416                            if (mCount == N) {
17417                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17418                            }
17419                        }
17420                    }
17421                }
17422            };
17423            synchronized (this) {
17424                uss.switching = true;
17425                mCurUserSwitchCallback = callback;
17426            }
17427            for (int i=0; i<N; i++) {
17428                try {
17429                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
17430                            newUserId, callback);
17431                } catch (RemoteException e) {
17432                }
17433            }
17434        } else {
17435            synchronized (this) {
17436                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17437            }
17438        }
17439        mUserSwitchObservers.finishBroadcast();
17440    }
17441
17442    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17443        synchronized (this) {
17444            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
17445            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
17446        }
17447    }
17448
17449    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
17450        mCurUserSwitchCallback = null;
17451        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
17452        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
17453                oldUserId, newUserId, uss));
17454    }
17455
17456    void userInitialized(UserStartedState uss, int newUserId) {
17457        completeSwitchAndInitalize(uss, newUserId, true, false);
17458    }
17459
17460    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
17461        completeSwitchAndInitalize(uss, newUserId, false, true);
17462    }
17463
17464    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
17465            boolean clearInitializing, boolean clearSwitching) {
17466        boolean unfrozen = false;
17467        synchronized (this) {
17468            if (clearInitializing) {
17469                uss.initializing = false;
17470                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
17471            }
17472            if (clearSwitching) {
17473                uss.switching = false;
17474            }
17475            if (!uss.switching && !uss.initializing) {
17476                mWindowManager.stopFreezingScreen();
17477                unfrozen = true;
17478            }
17479        }
17480        if (unfrozen) {
17481            final int N = mUserSwitchObservers.beginBroadcast();
17482            for (int i=0; i<N; i++) {
17483                try {
17484                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
17485                } catch (RemoteException e) {
17486                }
17487            }
17488            mUserSwitchObservers.finishBroadcast();
17489        }
17490    }
17491
17492    void scheduleStartProfilesLocked() {
17493        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
17494            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
17495                    DateUtils.SECOND_IN_MILLIS);
17496        }
17497    }
17498
17499    void startProfilesLocked() {
17500        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
17501        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17502                mCurrentUserId, false /* enabledOnly */);
17503        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
17504        for (UserInfo user : profiles) {
17505            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
17506                    && user.id != mCurrentUserId) {
17507                toStart.add(user);
17508            }
17509        }
17510        final int n = toStart.size();
17511        int i = 0;
17512        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
17513            startUserInBackground(toStart.get(i).id);
17514        }
17515        if (i < n) {
17516            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
17517        }
17518    }
17519
17520    void finishUserBoot(UserStartedState uss) {
17521        synchronized (this) {
17522            if (uss.mState == UserStartedState.STATE_BOOTING
17523                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
17524                uss.mState = UserStartedState.STATE_RUNNING;
17525                final int userId = uss.mHandle.getIdentifier();
17526                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
17527                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17528                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
17529                broadcastIntentLocked(null, null, intent,
17530                        null, null, 0, null, null,
17531                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
17532                        true, false, MY_PID, Process.SYSTEM_UID, userId);
17533            }
17534        }
17535    }
17536
17537    void finishUserSwitch(UserStartedState uss) {
17538        synchronized (this) {
17539            finishUserBoot(uss);
17540
17541            startProfilesLocked();
17542
17543            int num = mUserLru.size();
17544            int i = 0;
17545            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
17546                Integer oldUserId = mUserLru.get(i);
17547                UserStartedState oldUss = mStartedUsers.get(oldUserId);
17548                if (oldUss == null) {
17549                    // Shouldn't happen, but be sane if it does.
17550                    mUserLru.remove(i);
17551                    num--;
17552                    continue;
17553                }
17554                if (oldUss.mState == UserStartedState.STATE_STOPPING
17555                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
17556                    // This user is already stopping, doesn't count.
17557                    num--;
17558                    i++;
17559                    continue;
17560                }
17561                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
17562                    // Owner and current can't be stopped, but count as running.
17563                    i++;
17564                    continue;
17565                }
17566                // This is a user to be stopped.
17567                stopUserLocked(oldUserId, null);
17568                num--;
17569                i++;
17570            }
17571        }
17572    }
17573
17574    @Override
17575    public int stopUser(final int userId, final IStopUserCallback callback) {
17576        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17577                != PackageManager.PERMISSION_GRANTED) {
17578            String msg = "Permission Denial: switchUser() from pid="
17579                    + Binder.getCallingPid()
17580                    + ", uid=" + Binder.getCallingUid()
17581                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17582            Slog.w(TAG, msg);
17583            throw new SecurityException(msg);
17584        }
17585        if (userId <= 0) {
17586            throw new IllegalArgumentException("Can't stop primary user " + userId);
17587        }
17588        synchronized (this) {
17589            return stopUserLocked(userId, callback);
17590        }
17591    }
17592
17593    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
17594        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
17595        if (mCurrentUserId == userId) {
17596            return ActivityManager.USER_OP_IS_CURRENT;
17597        }
17598
17599        final UserStartedState uss = mStartedUsers.get(userId);
17600        if (uss == null) {
17601            // User is not started, nothing to do...  but we do need to
17602            // callback if requested.
17603            if (callback != null) {
17604                mHandler.post(new Runnable() {
17605                    @Override
17606                    public void run() {
17607                        try {
17608                            callback.userStopped(userId);
17609                        } catch (RemoteException e) {
17610                        }
17611                    }
17612                });
17613            }
17614            return ActivityManager.USER_OP_SUCCESS;
17615        }
17616
17617        if (callback != null) {
17618            uss.mStopCallbacks.add(callback);
17619        }
17620
17621        if (uss.mState != UserStartedState.STATE_STOPPING
17622                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17623            uss.mState = UserStartedState.STATE_STOPPING;
17624            updateStartedUserArrayLocked();
17625
17626            long ident = Binder.clearCallingIdentity();
17627            try {
17628                // We are going to broadcast ACTION_USER_STOPPING and then
17629                // once that is done send a final ACTION_SHUTDOWN and then
17630                // stop the user.
17631                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
17632                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17633                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
17634                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
17635                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
17636                // This is the result receiver for the final shutdown broadcast.
17637                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
17638                    @Override
17639                    public void performReceive(Intent intent, int resultCode, String data,
17640                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17641                        finishUserStop(uss);
17642                    }
17643                };
17644                // This is the result receiver for the initial stopping broadcast.
17645                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
17646                    @Override
17647                    public void performReceive(Intent intent, int resultCode, String data,
17648                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
17649                        // On to the next.
17650                        synchronized (ActivityManagerService.this) {
17651                            if (uss.mState != UserStartedState.STATE_STOPPING) {
17652                                // Whoops, we are being started back up.  Abort, abort!
17653                                return;
17654                            }
17655                            uss.mState = UserStartedState.STATE_SHUTDOWN;
17656                        }
17657                        mBatteryStatsService.noteEvent(
17658                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
17659                                Integer.toString(userId), userId);
17660                        mSystemServiceManager.stopUser(userId);
17661                        broadcastIntentLocked(null, null, shutdownIntent,
17662                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
17663                                true, false, MY_PID, Process.SYSTEM_UID, userId);
17664                    }
17665                };
17666                // Kick things off.
17667                broadcastIntentLocked(null, null, stoppingIntent,
17668                        null, stoppingReceiver, 0, null, null,
17669                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
17670                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
17671            } finally {
17672                Binder.restoreCallingIdentity(ident);
17673            }
17674        }
17675
17676        return ActivityManager.USER_OP_SUCCESS;
17677    }
17678
17679    void finishUserStop(UserStartedState uss) {
17680        final int userId = uss.mHandle.getIdentifier();
17681        boolean stopped;
17682        ArrayList<IStopUserCallback> callbacks;
17683        synchronized (this) {
17684            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
17685            if (mStartedUsers.get(userId) != uss) {
17686                stopped = false;
17687            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
17688                stopped = false;
17689            } else {
17690                stopped = true;
17691                // User can no longer run.
17692                mStartedUsers.remove(userId);
17693                mUserLru.remove(Integer.valueOf(userId));
17694                updateStartedUserArrayLocked();
17695
17696                // Clean up all state and processes associated with the user.
17697                // Kill all the processes for the user.
17698                forceStopUserLocked(userId, "finish user");
17699            }
17700        }
17701
17702        // Explicitly remove the old information in mRecentTasks.
17703        removeRecentTasksForUser(userId);
17704
17705        for (int i=0; i<callbacks.size(); i++) {
17706            try {
17707                if (stopped) callbacks.get(i).userStopped(userId);
17708                else callbacks.get(i).userStopAborted(userId);
17709            } catch (RemoteException e) {
17710            }
17711        }
17712
17713        if (stopped) {
17714            mSystemServiceManager.cleanupUser(userId);
17715            synchronized (this) {
17716                mStackSupervisor.removeUserLocked(userId);
17717            }
17718        }
17719    }
17720
17721    @Override
17722    public UserInfo getCurrentUser() {
17723        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
17724                != PackageManager.PERMISSION_GRANTED) && (
17725                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17726                != PackageManager.PERMISSION_GRANTED)) {
17727            String msg = "Permission Denial: getCurrentUser() from pid="
17728                    + Binder.getCallingPid()
17729                    + ", uid=" + Binder.getCallingUid()
17730                    + " requires " + INTERACT_ACROSS_USERS;
17731            Slog.w(TAG, msg);
17732            throw new SecurityException(msg);
17733        }
17734        synchronized (this) {
17735            return getUserManagerLocked().getUserInfo(mCurrentUserId);
17736        }
17737    }
17738
17739    int getCurrentUserIdLocked() {
17740        return mCurrentUserId;
17741    }
17742
17743    @Override
17744    public boolean isUserRunning(int userId, boolean orStopped) {
17745        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17746                != PackageManager.PERMISSION_GRANTED) {
17747            String msg = "Permission Denial: isUserRunning() from pid="
17748                    + Binder.getCallingPid()
17749                    + ", uid=" + Binder.getCallingUid()
17750                    + " requires " + INTERACT_ACROSS_USERS;
17751            Slog.w(TAG, msg);
17752            throw new SecurityException(msg);
17753        }
17754        synchronized (this) {
17755            return isUserRunningLocked(userId, orStopped);
17756        }
17757    }
17758
17759    boolean isUserRunningLocked(int userId, boolean orStopped) {
17760        UserStartedState state = mStartedUsers.get(userId);
17761        if (state == null) {
17762            return false;
17763        }
17764        if (orStopped) {
17765            return true;
17766        }
17767        return state.mState != UserStartedState.STATE_STOPPING
17768                && state.mState != UserStartedState.STATE_SHUTDOWN;
17769    }
17770
17771    @Override
17772    public int[] getRunningUserIds() {
17773        if (checkCallingPermission(INTERACT_ACROSS_USERS)
17774                != PackageManager.PERMISSION_GRANTED) {
17775            String msg = "Permission Denial: isUserRunning() from pid="
17776                    + Binder.getCallingPid()
17777                    + ", uid=" + Binder.getCallingUid()
17778                    + " requires " + INTERACT_ACROSS_USERS;
17779            Slog.w(TAG, msg);
17780            throw new SecurityException(msg);
17781        }
17782        synchronized (this) {
17783            return mStartedUserArray;
17784        }
17785    }
17786
17787    private void updateStartedUserArrayLocked() {
17788        int num = 0;
17789        for (int i=0; i<mStartedUsers.size();  i++) {
17790            UserStartedState uss = mStartedUsers.valueAt(i);
17791            // This list does not include stopping users.
17792            if (uss.mState != UserStartedState.STATE_STOPPING
17793                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17794                num++;
17795            }
17796        }
17797        mStartedUserArray = new int[num];
17798        num = 0;
17799        for (int i=0; i<mStartedUsers.size();  i++) {
17800            UserStartedState uss = mStartedUsers.valueAt(i);
17801            if (uss.mState != UserStartedState.STATE_STOPPING
17802                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
17803                mStartedUserArray[num] = mStartedUsers.keyAt(i);
17804                num++;
17805            }
17806        }
17807    }
17808
17809    @Override
17810    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
17811        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17812                != PackageManager.PERMISSION_GRANTED) {
17813            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
17814                    + Binder.getCallingPid()
17815                    + ", uid=" + Binder.getCallingUid()
17816                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17817            Slog.w(TAG, msg);
17818            throw new SecurityException(msg);
17819        }
17820
17821        mUserSwitchObservers.register(observer);
17822    }
17823
17824    @Override
17825    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
17826        mUserSwitchObservers.unregister(observer);
17827    }
17828
17829    private boolean userExists(int userId) {
17830        if (userId == 0) {
17831            return true;
17832        }
17833        UserManagerService ums = getUserManagerLocked();
17834        return ums != null ? (ums.getUserInfo(userId) != null) : false;
17835    }
17836
17837    int[] getUsersLocked() {
17838        UserManagerService ums = getUserManagerLocked();
17839        return ums != null ? ums.getUserIds() : new int[] { 0 };
17840    }
17841
17842    UserManagerService getUserManagerLocked() {
17843        if (mUserManager == null) {
17844            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
17845            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
17846        }
17847        return mUserManager;
17848    }
17849
17850    private int applyUserId(int uid, int userId) {
17851        return UserHandle.getUid(userId, uid);
17852    }
17853
17854    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
17855        if (info == null) return null;
17856        ApplicationInfo newInfo = new ApplicationInfo(info);
17857        newInfo.uid = applyUserId(info.uid, userId);
17858        newInfo.dataDir = USER_DATA_DIR + userId + "/"
17859                + info.packageName;
17860        return newInfo;
17861    }
17862
17863    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
17864        if (aInfo == null
17865                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
17866            return aInfo;
17867        }
17868
17869        ActivityInfo info = new ActivityInfo(aInfo);
17870        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
17871        return info;
17872    }
17873
17874    private final class LocalService extends ActivityManagerInternal {
17875        @Override
17876        public void goingToSleep() {
17877            ActivityManagerService.this.goingToSleep();
17878        }
17879
17880        @Override
17881        public void wakingUp() {
17882            ActivityManagerService.this.wakingUp();
17883        }
17884
17885        @Override
17886        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
17887                String processName, String abiOverride, int uid, Runnable crashHandler) {
17888            synchronized(ActivityManagerService.this) {
17889                ApplicationInfo info = new ApplicationInfo();
17890                // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
17891                // For isolated processes, the former contains the parent's uid and the latter the
17892                // actual uid of the isolated process.
17893                // In the special case introduced by this method (which is, starting an isolated
17894                // process directly from the SystemServer without an actual parent app process) the
17895                // closest thing to a parent's uid is SYSTEM_UID.
17896                // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
17897                // the |isolated| logic in the ProcessRecord constructor.
17898                info.uid = Process.SYSTEM_UID;
17899                info.processName = processName;
17900                info.className = entryPoint;
17901                info.packageName = "android";
17902                startProcessLocked(processName, info /* info */, false /* knownToBeDead */,
17903                        0 /* intentFlags */, ""  /* hostingType */, null /* hostingName */,
17904                        true /* allowWhileBooting */, true /* isolated */, uid,
17905                        true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
17906                        crashHandler);
17907                return 0;
17908            }
17909        }
17910    }
17911
17912    /**
17913     * An implementation of IAppTask, that allows an app to manage its own tasks via
17914     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
17915     * only the process that calls getAppTasks() can call the AppTask methods.
17916     */
17917    class AppTaskImpl extends IAppTask.Stub {
17918        private int mTaskId;
17919        private int mCallingUid;
17920
17921        public AppTaskImpl(int taskId, int callingUid) {
17922            mTaskId = taskId;
17923            mCallingUid = callingUid;
17924        }
17925
17926        @Override
17927        public void finishAndRemoveTask() {
17928            // Ensure that we are called from the same process that created this AppTask
17929            if (mCallingUid != Binder.getCallingUid()) {
17930                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17931                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17932                return;
17933            }
17934
17935            synchronized (ActivityManagerService.this) {
17936                long origId = Binder.clearCallingIdentity();
17937                try {
17938                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17939                    if (tr != null) {
17940                        // Only kill the process if we are not a new document
17941                        int flags = tr.getBaseIntent().getFlags();
17942                        boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
17943                                Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
17944                        removeTaskByIdLocked(mTaskId,
17945                                !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
17946                    }
17947                } finally {
17948                    Binder.restoreCallingIdentity(origId);
17949                }
17950            }
17951        }
17952
17953        @Override
17954        public ActivityManager.RecentTaskInfo getTaskInfo() {
17955            // Ensure that we are called from the same process that created this AppTask
17956            if (mCallingUid != Binder.getCallingUid()) {
17957                Slog.w(TAG, "finishAndRemoveTask: caller " + mCallingUid
17958                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
17959                return null;
17960            }
17961
17962            synchronized (ActivityManagerService.this) {
17963                long origId = Binder.clearCallingIdentity();
17964                try {
17965                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
17966                    if (tr != null) {
17967                        return createRecentTaskInfoFromTaskRecord(tr);
17968                    }
17969                } finally {
17970                    Binder.restoreCallingIdentity(origId);
17971                }
17972                return null;
17973            }
17974        }
17975    }
17976}
17977