ActivityManagerService.java revision 36927a3600520686495cba4f3fc19e1445f8a64c
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.ApplicationThreadNative;
37import android.app.IActivityContainer;
38import android.app.IActivityContainerCallback;
39import android.app.IAppTask;
40import android.app.ProfilerInfo;
41import android.app.admin.DevicePolicyManager;
42import android.app.usage.UsageEvents;
43import android.app.usage.UsageStatsManagerInternal;
44import android.appwidget.AppWidgetManager;
45import android.content.res.Resources;
46import android.graphics.Bitmap;
47import android.graphics.Point;
48import android.graphics.Rect;
49import android.os.BatteryStats;
50import android.os.PersistableBundle;
51import android.service.voice.IVoiceInteractionSession;
52import android.util.ArrayMap;
53import android.util.ArraySet;
54import android.util.SparseIntArray;
55
56import com.android.internal.R;
57import com.android.internal.annotations.GuardedBy;
58import com.android.internal.app.IAppOpsService;
59import com.android.internal.app.IVoiceInteractor;
60import com.android.internal.app.ProcessMap;
61import com.android.internal.app.ProcessStats;
62import com.android.internal.content.PackageMonitor;
63import com.android.internal.os.BackgroundThread;
64import com.android.internal.os.BatteryStatsImpl;
65import com.android.internal.os.ProcessCpuTracker;
66import com.android.internal.os.TransferPipe;
67import com.android.internal.os.Zygote;
68import com.android.internal.util.FastPrintWriter;
69import com.android.internal.util.FastXmlSerializer;
70import com.android.internal.util.MemInfoReader;
71import com.android.internal.util.Preconditions;
72import com.android.server.AppOpsService;
73import com.android.server.AttributeCache;
74import com.android.server.IntentResolver;
75import com.android.server.LocalServices;
76import com.android.server.ServiceThread;
77import com.android.server.SystemService;
78import com.android.server.SystemServiceManager;
79import com.android.server.Watchdog;
80import com.android.server.am.ActivityStack.ActivityState;
81import com.android.server.firewall.IntentFirewall;
82import com.android.server.pm.UserManagerService;
83import com.android.server.wm.AppTransition;
84import com.android.server.wm.WindowManagerService;
85import com.google.android.collect.Lists;
86import com.google.android.collect.Maps;
87
88import libcore.io.IoUtils;
89
90import org.xmlpull.v1.XmlPullParser;
91import org.xmlpull.v1.XmlPullParserException;
92import org.xmlpull.v1.XmlSerializer;
93
94import android.app.Activity;
95import android.app.ActivityManager;
96import android.app.ActivityManager.RunningTaskInfo;
97import android.app.ActivityManager.StackInfo;
98import android.app.ActivityManagerInternal;
99import android.app.ActivityManagerNative;
100import android.app.ActivityOptions;
101import android.app.ActivityThread;
102import android.app.AlertDialog;
103import android.app.AppGlobals;
104import android.app.ApplicationErrorReport;
105import android.app.Dialog;
106import android.app.IActivityController;
107import android.app.IApplicationThread;
108import android.app.IInstrumentationWatcher;
109import android.app.INotificationManager;
110import android.app.IProcessObserver;
111import android.app.IServiceConnection;
112import android.app.IStopUserCallback;
113import android.app.IUiAutomationConnection;
114import android.app.IUserSwitchObserver;
115import android.app.Instrumentation;
116import android.app.Notification;
117import android.app.NotificationManager;
118import android.app.PendingIntent;
119import android.app.backup.IBackupManager;
120import android.content.ActivityNotFoundException;
121import android.content.BroadcastReceiver;
122import android.content.ClipData;
123import android.content.ComponentCallbacks2;
124import android.content.ComponentName;
125import android.content.ContentProvider;
126import android.content.ContentResolver;
127import android.content.Context;
128import android.content.DialogInterface;
129import android.content.IContentProvider;
130import android.content.IIntentReceiver;
131import android.content.IIntentSender;
132import android.content.Intent;
133import android.content.IntentFilter;
134import android.content.IntentSender;
135import android.content.pm.ActivityInfo;
136import android.content.pm.ApplicationInfo;
137import android.content.pm.ConfigurationInfo;
138import android.content.pm.IPackageDataObserver;
139import android.content.pm.IPackageManager;
140import android.content.pm.InstrumentationInfo;
141import android.content.pm.PackageInfo;
142import android.content.pm.PackageManager;
143import android.content.pm.ParceledListSlice;
144import android.content.pm.UserInfo;
145import android.content.pm.PackageManager.NameNotFoundException;
146import android.content.pm.PathPermission;
147import android.content.pm.ProviderInfo;
148import android.content.pm.ResolveInfo;
149import android.content.pm.ServiceInfo;
150import android.content.res.CompatibilityInfo;
151import android.content.res.Configuration;
152import android.net.Proxy;
153import android.net.ProxyInfo;
154import android.net.Uri;
155import android.os.Binder;
156import android.os.Build;
157import android.os.Bundle;
158import android.os.Debug;
159import android.os.DropBoxManager;
160import android.os.Environment;
161import android.os.FactoryTest;
162import android.os.FileObserver;
163import android.os.FileUtils;
164import android.os.Handler;
165import android.os.IBinder;
166import android.os.IPermissionController;
167import android.os.IRemoteCallback;
168import android.os.IUserManager;
169import android.os.Looper;
170import android.os.Message;
171import android.os.Parcel;
172import android.os.ParcelFileDescriptor;
173import android.os.Process;
174import android.os.RemoteCallbackList;
175import android.os.RemoteException;
176import android.os.SELinux;
177import android.os.ServiceManager;
178import android.os.StrictMode;
179import android.os.SystemClock;
180import android.os.SystemProperties;
181import android.os.UpdateLock;
182import android.os.UserHandle;
183import android.provider.Settings;
184import android.text.format.DateUtils;
185import android.text.format.Time;
186import android.util.AtomicFile;
187import android.util.EventLog;
188import android.util.Log;
189import android.util.Pair;
190import android.util.PrintWriterPrinter;
191import android.util.Slog;
192import android.util.SparseArray;
193import android.util.TimeUtils;
194import android.util.Xml;
195import android.view.Gravity;
196import android.view.LayoutInflater;
197import android.view.View;
198import android.view.WindowManager;
199
200import java.io.BufferedInputStream;
201import java.io.BufferedOutputStream;
202import java.io.DataInputStream;
203import java.io.DataOutputStream;
204import java.io.File;
205import java.io.FileDescriptor;
206import java.io.FileInputStream;
207import java.io.FileNotFoundException;
208import java.io.FileOutputStream;
209import java.io.IOException;
210import java.io.InputStreamReader;
211import java.io.PrintWriter;
212import java.io.StringWriter;
213import java.lang.ref.WeakReference;
214import java.util.ArrayList;
215import java.util.Arrays;
216import java.util.Collections;
217import java.util.Comparator;
218import java.util.HashMap;
219import java.util.HashSet;
220import java.util.Iterator;
221import java.util.List;
222import java.util.Locale;
223import java.util.Map;
224import java.util.Set;
225import java.util.concurrent.atomic.AtomicBoolean;
226import java.util.concurrent.atomic.AtomicLong;
227
228public final class ActivityManagerService extends ActivityManagerNative
229        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
230
231    private static final String USER_DATA_DIR = "/data/user/";
232    // File that stores last updated system version and called preboot receivers
233    static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
234
235    static final String TAG = "ActivityManager";
236    static final String TAG_MU = "ActivityManagerServiceMU";
237    static final boolean DEBUG = false;
238    static final boolean localLOGV = DEBUG;
239    static final boolean DEBUG_BACKUP = localLOGV || false;
240    static final boolean DEBUG_BROADCAST = localLOGV || false;
241    static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
242    static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
243    static final boolean DEBUG_CLEANUP = localLOGV || false;
244    static final boolean DEBUG_CONFIGURATION = localLOGV || false;
245    static final boolean DEBUG_FOCUS = false;
246    static final boolean DEBUG_IMMERSIVE = localLOGV || false;
247    static final boolean DEBUG_MU = localLOGV || false;
248    static final boolean DEBUG_OOM_ADJ = localLOGV || false;
249    static final boolean DEBUG_LRU = localLOGV || false;
250    static final boolean DEBUG_PAUSE = localLOGV || false;
251    static final boolean DEBUG_POWER = localLOGV || false;
252    static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
253    static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
254    static final boolean DEBUG_PROCESSES = localLOGV || false;
255    static final boolean DEBUG_PROVIDER = localLOGV || false;
256    static final boolean DEBUG_RESULTS = localLOGV || false;
257    static final boolean DEBUG_SERVICE = localLOGV || false;
258    static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
259    static final boolean DEBUG_STACK = localLOGV || false;
260    static final boolean DEBUG_SWITCH = localLOGV || false;
261    static final boolean DEBUG_TASKS = localLOGV || false;
262    static final boolean DEBUG_THUMBNAILS = localLOGV || false;
263    static final boolean DEBUG_TRANSITION = localLOGV || false;
264    static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
265    static final boolean DEBUG_USER_LEAVING = localLOGV || false;
266    static final boolean DEBUG_VISBILITY = localLOGV || false;
267    static final boolean DEBUG_PSS = localLOGV || false;
268    static final boolean DEBUG_LOCKSCREEN = localLOGV || false;
269    static final boolean DEBUG_RECENTS = localLOGV || false;
270    static final boolean VALIDATE_TOKENS = false;
271    static final boolean SHOW_ACTIVITY_START_TIME = true;
272
273    // Control over CPU and battery monitoring.
274    static final long BATTERY_STATS_TIME = 30*60*1000;      // write battery stats every 30 minutes.
275    static final boolean MONITOR_CPU_USAGE = true;
276    static final long MONITOR_CPU_MIN_TIME = 5*1000;        // don't sample cpu less than every 5 seconds.
277    static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;    // wait possibly forever for next cpu sample.
278    static final boolean MONITOR_THREAD_CPU_USAGE = false;
279
280    // The flags that are set for all calls we make to the package manager.
281    static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
282
283    private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
284
285    static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
286
287    // Maximum number recent bitmaps to keep in memory.
288    static final int MAX_RECENT_BITMAPS = 5;
289
290    // Amount of time after a call to stopAppSwitches() during which we will
291    // prevent further untrusted switches from happening.
292    static final long APP_SWITCH_DELAY_TIME = 5*1000;
293
294    // How long we wait for a launched process to attach to the activity manager
295    // before we decide it's never going to come up for real.
296    static final int PROC_START_TIMEOUT = 10*1000;
297
298    // How long we wait for a launched process to attach to the activity manager
299    // before we decide it's never going to come up for real, when the process was
300    // started with a wrapper for instrumentation (such as Valgrind) because it
301    // could take much longer than usual.
302    static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
303
304    // How long to wait after going idle before forcing apps to GC.
305    static final int GC_TIMEOUT = 5*1000;
306
307    // The minimum amount of time between successive GC requests for a process.
308    static final int GC_MIN_INTERVAL = 60*1000;
309
310    // The minimum amount of time between successive PSS requests for a process.
311    static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
312
313    // The minimum amount of time between successive PSS requests for a process
314    // when the request is due to the memory state being lowered.
315    static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
316
317    // The rate at which we check for apps using excessive power -- 15 mins.
318    static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
319
320    // The minimum sample duration we will allow before deciding we have
321    // enough data on wake locks to start killing things.
322    static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
323
324    // The minimum sample duration we will allow before deciding we have
325    // enough data on CPU usage to start killing things.
326    static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
327
328    // How long we allow a receiver to run before giving up on it.
329    static final int BROADCAST_FG_TIMEOUT = 10*1000;
330    static final int BROADCAST_BG_TIMEOUT = 60*1000;
331
332    // How long we wait until we timeout on key dispatching.
333    static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
334
335    // How long we wait until we timeout on key dispatching during instrumentation.
336    static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
337
338    // Amount of time we wait for observers to handle a user switch before
339    // giving up on them and unfreezing the screen.
340    static final int USER_SWITCH_TIMEOUT = 2*1000;
341
342    // Maximum number of users we allow to be running at a time.
343    static final int MAX_RUNNING_USERS = 3;
344
345    // How long to wait in getAssistContextExtras for the activity and foreground services
346    // to respond with the result.
347    static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
348
349    // Maximum number of persisted Uri grants a package is allowed
350    static final int MAX_PERSISTED_URI_GRANTS = 128;
351
352    static final int MY_PID = Process.myPid();
353
354    static final String[] EMPTY_STRING_ARRAY = new String[0];
355
356    // How many bytes to write into the dropbox log before truncating
357    static final int DROPBOX_MAX_SIZE = 256 * 1024;
358
359    // Access modes for handleIncomingUser.
360    static final int ALLOW_NON_FULL = 0;
361    static final int ALLOW_NON_FULL_IN_PROFILE = 1;
362    static final int ALLOW_FULL_ONLY = 2;
363
364    static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
365
366    /** All system services */
367    SystemServiceManager mSystemServiceManager;
368
369    /** Run all ActivityStacks through this */
370    ActivityStackSupervisor mStackSupervisor;
371
372    public IntentFirewall mIntentFirewall;
373
374    // Whether we should show our dialogs (ANR, crash, etc) or just perform their
375    // default actuion automatically.  Important for devices without direct input
376    // devices.
377    private boolean mShowDialogs = true;
378
379    BroadcastQueue mFgBroadcastQueue;
380    BroadcastQueue mBgBroadcastQueue;
381    // Convenient for easy iteration over the queues. Foreground is first
382    // so that dispatch of foreground broadcasts gets precedence.
383    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
384
385    BroadcastQueue broadcastQueueForIntent(Intent intent) {
386        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
387        if (DEBUG_BACKGROUND_BROADCAST) {
388            Slog.i(TAG, "Broadcast intent " + intent + " on "
389                    + (isFg ? "foreground" : "background")
390                    + " queue");
391        }
392        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
393    }
394
395    BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
396        for (BroadcastQueue queue : mBroadcastQueues) {
397            BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
398            if (r != null) {
399                return r;
400            }
401        }
402        return null;
403    }
404
405    /**
406     * Activity we have told the window manager to have key focus.
407     */
408    ActivityRecord mFocusedActivity = null;
409
410    /**
411     * List of intents that were used to start the most recent tasks.
412     */
413    ArrayList<TaskRecord> mRecentTasks;
414    ArraySet<TaskRecord> mTmpRecents = new ArraySet<TaskRecord>();
415
416    /**
417     * For addAppTask: cached of the last activity component that was added.
418     */
419    ComponentName mLastAddedTaskComponent;
420
421    /**
422     * For addAppTask: cached of the last activity uid that was added.
423     */
424    int mLastAddedTaskUid;
425
426    /**
427     * For addAppTask: cached of the last ActivityInfo that was added.
428     */
429    ActivityInfo mLastAddedTaskActivity;
430
431    public class PendingAssistExtras extends Binder implements Runnable {
432        public final ActivityRecord activity;
433        public boolean haveResult = false;
434        public Bundle result = null;
435        public PendingAssistExtras(ActivityRecord _activity) {
436            activity = _activity;
437        }
438        @Override
439        public void run() {
440            Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
441            synchronized (this) {
442                haveResult = true;
443                notifyAll();
444            }
445        }
446    }
447
448    final ArrayList<PendingAssistExtras> mPendingAssistExtras
449            = new ArrayList<PendingAssistExtras>();
450
451    /**
452     * Process management.
453     */
454    final ProcessList mProcessList = new ProcessList();
455
456    /**
457     * All of the applications we currently have running organized by name.
458     * The keys are strings of the application package name (as
459     * returned by the package manager), and the keys are ApplicationRecord
460     * objects.
461     */
462    final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
463
464    /**
465     * Tracking long-term execution of processes to look for abuse and other
466     * bad app behavior.
467     */
468    final ProcessStatsService mProcessStats;
469
470    /**
471     * The currently running isolated processes.
472     */
473    final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
474
475    /**
476     * Counter for assigning isolated process uids, to avoid frequently reusing the
477     * same ones.
478     */
479    int mNextIsolatedProcessUid = 0;
480
481    /**
482     * The currently running heavy-weight process, if any.
483     */
484    ProcessRecord mHeavyWeightProcess = null;
485
486    /**
487     * The last time that various processes have crashed.
488     */
489    final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
490
491    /**
492     * Information about a process that is currently marked as bad.
493     */
494    static final class BadProcessInfo {
495        BadProcessInfo(long time, String shortMsg, String longMsg, String stack) {
496            this.time = time;
497            this.shortMsg = shortMsg;
498            this.longMsg = longMsg;
499            this.stack = stack;
500        }
501
502        final long time;
503        final String shortMsg;
504        final String longMsg;
505        final String stack;
506    }
507
508    /**
509     * Set of applications that we consider to be bad, and will reject
510     * incoming broadcasts from (which the user has no control over).
511     * Processes are added to this set when they have crashed twice within
512     * a minimum amount of time; they are removed from it when they are
513     * later restarted (hopefully due to some user action).  The value is the
514     * time it was added to the list.
515     */
516    final ProcessMap<BadProcessInfo> mBadProcesses = new ProcessMap<BadProcessInfo>();
517
518    /**
519     * All of the processes we currently have running organized by pid.
520     * The keys are the pid running the application.
521     *
522     * <p>NOTE: This object is protected by its own lock, NOT the global
523     * activity manager lock!
524     */
525    final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
526
527    /**
528     * All of the processes that have been forced to be foreground.  The key
529     * is the pid of the caller who requested it (we hold a death
530     * link on it).
531     */
532    abstract class ForegroundToken implements IBinder.DeathRecipient {
533        int pid;
534        IBinder token;
535    }
536    final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
537
538    /**
539     * List of records for processes that someone had tried to start before the
540     * system was ready.  We don't start them at that point, but ensure they
541     * are started by the time booting is complete.
542     */
543    final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
544
545    /**
546     * List of persistent applications that are in the process
547     * of being started.
548     */
549    final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
550
551    /**
552     * Processes that are being forcibly torn down.
553     */
554    final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
555
556    /**
557     * List of running applications, sorted by recent usage.
558     * The first entry in the list is the least recently used.
559     */
560    final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
561
562    /**
563     * Where in mLruProcesses that the processes hosting activities start.
564     */
565    int mLruProcessActivityStart = 0;
566
567    /**
568     * Where in mLruProcesses that the processes hosting services start.
569     * This is after (lower index) than mLruProcessesActivityStart.
570     */
571    int mLruProcessServiceStart = 0;
572
573    /**
574     * List of processes that should gc as soon as things are idle.
575     */
576    final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
577
578    /**
579     * Processes we want to collect PSS data from.
580     */
581    final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
582
583    /**
584     * Last time we requested PSS data of all processes.
585     */
586    long mLastFullPssTime = SystemClock.uptimeMillis();
587
588    /**
589     * If set, the next time we collect PSS data we should do a full collection
590     * with data from native processes and the kernel.
591     */
592    boolean mFullPssPending = false;
593
594    /**
595     * This is the process holding what we currently consider to be
596     * the "home" activity.
597     */
598    ProcessRecord mHomeProcess;
599
600    /**
601     * This is the process holding the activity the user last visited that
602     * is in a different process from the one they are currently in.
603     */
604    ProcessRecord mPreviousProcess;
605
606    /**
607     * The time at which the previous process was last visible.
608     */
609    long mPreviousProcessVisibleTime;
610
611    /**
612     * Which uses have been started, so are allowed to run code.
613     */
614    final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
615
616    /**
617     * LRU list of history of current users.  Most recently current is at the end.
618     */
619    final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
620
621    /**
622     * Constant array of the users that are currently started.
623     */
624    int[] mStartedUserArray = new int[] { 0 };
625
626    /**
627     * Registered observers of the user switching mechanics.
628     */
629    final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
630            = new RemoteCallbackList<IUserSwitchObserver>();
631
632    /**
633     * Currently active user switch.
634     */
635    Object mCurUserSwitchCallback;
636
637    /**
638     * Packages that the user has asked to have run in screen size
639     * compatibility mode instead of filling the screen.
640     */
641    final CompatModePackages mCompatModePackages;
642
643    /**
644     * Set of IntentSenderRecord objects that are currently active.
645     */
646    final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
647            = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
648
649    /**
650     * Fingerprints (hashCode()) of stack traces that we've
651     * already logged DropBox entries for.  Guarded by itself.  If
652     * something (rogue user app) forces this over
653     * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
654     */
655    private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
656    private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
657
658    /**
659     * Strict Mode background batched logging state.
660     *
661     * The string buffer is guarded by itself, and its lock is also
662     * used to determine if another batched write is already
663     * in-flight.
664     */
665    private final StringBuilder mStrictModeBuffer = new StringBuilder();
666
667    /**
668     * Keeps track of all IIntentReceivers that have been registered for
669     * broadcasts.  Hash keys are the receiver IBinder, hash value is
670     * a ReceiverList.
671     */
672    final HashMap<IBinder, ReceiverList> mRegisteredReceivers =
673            new HashMap<IBinder, ReceiverList>();
674
675    /**
676     * Resolver for broadcast intents to registered receivers.
677     * Holds BroadcastFilter (subclass of IntentFilter).
678     */
679    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
680            = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
681        @Override
682        protected boolean allowFilterResult(
683                BroadcastFilter filter, List<BroadcastFilter> dest) {
684            IBinder target = filter.receiverList.receiver.asBinder();
685            for (int i=dest.size()-1; i>=0; i--) {
686                if (dest.get(i).receiverList.receiver.asBinder() == target) {
687                    return false;
688                }
689            }
690            return true;
691        }
692
693        @Override
694        protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
695            if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
696                    || userId == filter.owningUserId) {
697                return super.newResult(filter, match, userId);
698            }
699            return null;
700        }
701
702        @Override
703        protected BroadcastFilter[] newArray(int size) {
704            return new BroadcastFilter[size];
705        }
706
707        @Override
708        protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
709            return packageName.equals(filter.packageName);
710        }
711    };
712
713    /**
714     * State of all active sticky broadcasts per user.  Keys are the action of the
715     * sticky Intent, values are an ArrayList of all broadcasted intents with
716     * that action (which should usually be one).  The SparseArray is keyed
717     * by the user ID the sticky is for, and can include UserHandle.USER_ALL
718     * for stickies that are sent to all users.
719     */
720    final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
721            new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
722
723    final ActiveServices mServices;
724
725    /**
726     * Backup/restore process management
727     */
728    String mBackupAppName = null;
729    BackupRecord mBackupTarget = null;
730
731    final ProviderMap mProviderMap;
732
733    /**
734     * List of content providers who have clients waiting for them.  The
735     * application is currently being launched and the provider will be
736     * removed from this list once it is published.
737     */
738    final ArrayList<ContentProviderRecord> mLaunchingProviders
739            = new ArrayList<ContentProviderRecord>();
740
741    /**
742     * File storing persisted {@link #mGrantedUriPermissions}.
743     */
744    private final AtomicFile mGrantFile;
745
746    /** XML constants used in {@link #mGrantFile} */
747    private static final String TAG_URI_GRANTS = "uri-grants";
748    private static final String TAG_URI_GRANT = "uri-grant";
749    private static final String ATTR_USER_HANDLE = "userHandle";
750    private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
751    private static final String ATTR_TARGET_USER_ID = "targetUserId";
752    private static final String ATTR_SOURCE_PKG = "sourcePkg";
753    private static final String ATTR_TARGET_PKG = "targetPkg";
754    private static final String ATTR_URI = "uri";
755    private static final String ATTR_MODE_FLAGS = "modeFlags";
756    private static final String ATTR_CREATED_TIME = "createdTime";
757    private static final String ATTR_PREFIX = "prefix";
758
759    /**
760     * Global set of specific {@link Uri} permissions that have been granted.
761     * This optimized lookup structure maps from {@link UriPermission#targetUid}
762     * to {@link UriPermission#uri} to {@link UriPermission}.
763     */
764    @GuardedBy("this")
765    private final SparseArray<ArrayMap<GrantUri, UriPermission>>
766            mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
767
768    public static class GrantUri {
769        public final int sourceUserId;
770        public final Uri uri;
771        public boolean prefix;
772
773        public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
774            this.sourceUserId = sourceUserId;
775            this.uri = uri;
776            this.prefix = prefix;
777        }
778
779        @Override
780        public int hashCode() {
781            return toString().hashCode();
782        }
783
784        @Override
785        public boolean equals(Object o) {
786            if (o instanceof GrantUri) {
787                GrantUri other = (GrantUri) o;
788                return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
789                        && prefix == other.prefix;
790            }
791            return false;
792        }
793
794        @Override
795        public String toString() {
796            String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
797            if (prefix) result += " [prefix]";
798            return result;
799        }
800
801        public String toSafeString() {
802            String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
803            if (prefix) result += " [prefix]";
804            return result;
805        }
806
807        public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
808            return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
809                    ContentProvider.getUriWithoutUserId(uri), false);
810        }
811    }
812
813    CoreSettingsObserver mCoreSettingsObserver;
814
815    /**
816     * Thread-local storage used to carry caller permissions over through
817     * indirect content-provider access.
818     */
819    private class Identity {
820        public int pid;
821        public int uid;
822
823        Identity(int _pid, int _uid) {
824            pid = _pid;
825            uid = _uid;
826        }
827    }
828
829    private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
830
831    /**
832     * All information we have collected about the runtime performance of
833     * any user id that can impact battery performance.
834     */
835    final BatteryStatsService mBatteryStatsService;
836
837    /**
838     * Information about component usage
839     */
840    UsageStatsManagerInternal mUsageStatsService;
841
842    /**
843     * Information about and control over application operations
844     */
845    final AppOpsService mAppOpsService;
846
847    /**
848     * Save recent tasks information across reboots.
849     */
850    final TaskPersister mTaskPersister;
851
852    /**
853     * Current configuration information.  HistoryRecord objects are given
854     * a reference to this object to indicate which configuration they are
855     * currently running in, so this object must be kept immutable.
856     */
857    Configuration mConfiguration = new Configuration();
858
859    /**
860     * Current sequencing integer of the configuration, for skipping old
861     * configurations.
862     */
863    int mConfigurationSeq = 0;
864
865    /**
866     * Hardware-reported OpenGLES version.
867     */
868    final int GL_ES_VERSION;
869
870    /**
871     * List of initialization arguments to pass to all processes when binding applications to them.
872     * For example, references to the commonly used services.
873     */
874    HashMap<String, IBinder> mAppBindArgs;
875
876    /**
877     * Temporary to avoid allocations.  Protected by main lock.
878     */
879    final StringBuilder mStringBuilder = new StringBuilder(256);
880
881    /**
882     * Used to control how we initialize the service.
883     */
884    ComponentName mTopComponent;
885    String mTopAction = Intent.ACTION_MAIN;
886    String mTopData;
887    boolean mProcessesReady = false;
888    boolean mSystemReady = false;
889    boolean mBooting = false;
890    boolean mWaitingUpdate = false;
891    boolean mDidUpdate = false;
892    boolean mOnBattery = false;
893    boolean mLaunchWarningShown = false;
894
895    Context mContext;
896
897    int mFactoryTest;
898
899    boolean mCheckedForSetup;
900
901    /**
902     * The time at which we will allow normal application switches again,
903     * after a call to {@link #stopAppSwitches()}.
904     */
905    long mAppSwitchesAllowedTime;
906
907    /**
908     * This is set to true after the first switch after mAppSwitchesAllowedTime
909     * is set; any switches after that will clear the time.
910     */
911    boolean mDidAppSwitch;
912
913    /**
914     * Last time (in realtime) at which we checked for power usage.
915     */
916    long mLastPowerCheckRealtime;
917
918    /**
919     * Last time (in uptime) at which we checked for power usage.
920     */
921    long mLastPowerCheckUptime;
922
923    /**
924     * Set while we are wanting to sleep, to prevent any
925     * activities from being started/resumed.
926     */
927    private boolean mSleeping = false;
928
929    /**
930     * Set while we are running a voice interaction.  This overrides
931     * sleeping while it is active.
932     */
933    private boolean mRunningVoice = false;
934
935    /**
936     * State of external calls telling us if the device is asleep.
937     */
938    private boolean mWentToSleep = false;
939
940    /**
941     * State of external call telling us if the lock screen is shown.
942     */
943    private boolean mLockScreenShown = false;
944
945    /**
946     * Set if we are shutting down the system, similar to sleeping.
947     */
948    boolean mShuttingDown = false;
949
950    /**
951     * Current sequence id for oom_adj computation traversal.
952     */
953    int mAdjSeq = 0;
954
955    /**
956     * Current sequence id for process LRU updating.
957     */
958    int mLruSeq = 0;
959
960    /**
961     * Keep track of the non-cached/empty process we last found, to help
962     * determine how to distribute cached/empty processes next time.
963     */
964    int mNumNonCachedProcs = 0;
965
966    /**
967     * Keep track of the number of cached hidden procs, to balance oom adj
968     * distribution between those and empty procs.
969     */
970    int mNumCachedHiddenProcs = 0;
971
972    /**
973     * Keep track of the number of service processes we last found, to
974     * determine on the next iteration which should be B services.
975     */
976    int mNumServiceProcs = 0;
977    int mNewNumAServiceProcs = 0;
978    int mNewNumServiceProcs = 0;
979
980    /**
981     * Allow the current computed overall memory level of the system to go down?
982     * This is set to false when we are killing processes for reasons other than
983     * memory management, so that the now smaller process list will not be taken as
984     * an indication that memory is tighter.
985     */
986    boolean mAllowLowerMemLevel = false;
987
988    /**
989     * The last computed memory level, for holding when we are in a state that
990     * processes are going away for other reasons.
991     */
992    int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
993
994    /**
995     * The last total number of process we have, to determine if changes actually look
996     * like a shrinking number of process due to lower RAM.
997     */
998    int mLastNumProcesses;
999
1000    /**
1001     * The uptime of the last time we performed idle maintenance.
1002     */
1003    long mLastIdleTime = SystemClock.uptimeMillis();
1004
1005    /**
1006     * Total time spent with RAM that has been added in the past since the last idle time.
1007     */
1008    long mLowRamTimeSinceLastIdle = 0;
1009
1010    /**
1011     * If RAM is currently low, when that horrible situation started.
1012     */
1013    long mLowRamStartTime = 0;
1014
1015    /**
1016     * For reporting to battery stats the current top application.
1017     */
1018    private String mCurResumedPackage = null;
1019    private int mCurResumedUid = -1;
1020
1021    /**
1022     * For reporting to battery stats the apps currently running foreground
1023     * service.  The ProcessMap is package/uid tuples; each of these contain
1024     * an array of the currently foreground processes.
1025     */
1026    final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1027            = new ProcessMap<ArrayList<ProcessRecord>>();
1028
1029    /**
1030     * This is set if we had to do a delayed dexopt of an app before launching
1031     * it, to increase the ANR timeouts in that case.
1032     */
1033    boolean mDidDexOpt;
1034
1035    /**
1036     * Set if the systemServer made a call to enterSafeMode.
1037     */
1038    boolean mSafeMode;
1039
1040    String mDebugApp = null;
1041    boolean mWaitForDebugger = false;
1042    boolean mDebugTransient = false;
1043    String mOrigDebugApp = null;
1044    boolean mOrigWaitForDebugger = false;
1045    boolean mAlwaysFinishActivities = false;
1046    IActivityController mController = null;
1047    String mProfileApp = null;
1048    ProcessRecord mProfileProc = null;
1049    String mProfileFile;
1050    ParcelFileDescriptor mProfileFd;
1051    int mSamplingInterval = 0;
1052    boolean mAutoStopProfiler = false;
1053    int mProfileType = 0;
1054    String mOpenGlTraceApp = null;
1055
1056    static class ProcessChangeItem {
1057        static final int CHANGE_ACTIVITIES = 1<<0;
1058        static final int CHANGE_PROCESS_STATE = 1<<1;
1059        int changes;
1060        int uid;
1061        int pid;
1062        int processState;
1063        boolean foregroundActivities;
1064    }
1065
1066    final RemoteCallbackList<IProcessObserver> mProcessObservers
1067            = new RemoteCallbackList<IProcessObserver>();
1068    ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1069
1070    final ArrayList<ProcessChangeItem> mPendingProcessChanges
1071            = new ArrayList<ProcessChangeItem>();
1072    final ArrayList<ProcessChangeItem> mAvailProcessChanges
1073            = new ArrayList<ProcessChangeItem>();
1074
1075    /**
1076     * Runtime CPU use collection thread.  This object's lock is used to
1077     * protect all related state.
1078     */
1079    final Thread mProcessCpuThread;
1080
1081    /**
1082     * Used to collect process stats when showing not responding dialog.
1083     * Protected by mProcessCpuThread.
1084     */
1085    final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1086            MONITOR_THREAD_CPU_USAGE);
1087    final AtomicLong mLastCpuTime = new AtomicLong(0);
1088    final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1089
1090    long mLastWriteTime = 0;
1091
1092    /**
1093     * Used to retain an update lock when the foreground activity is in
1094     * immersive mode.
1095     */
1096    final UpdateLock mUpdateLock = new UpdateLock("immersive");
1097
1098    /**
1099     * Set to true after the system has finished booting.
1100     */
1101    boolean mBooted = false;
1102
1103    int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1104    int mProcessLimitOverride = -1;
1105
1106    WindowManagerService mWindowManager;
1107
1108    final ActivityThread mSystemThread;
1109
1110    int mCurrentUserId = 0;
1111    int[] mCurrentProfileIds = new int[] {UserHandle.USER_OWNER}; // Accessed by ActivityStack
1112
1113    /**
1114     * Mapping from each known user ID to the profile group ID it is associated with.
1115     */
1116    SparseIntArray mUserProfileGroupIdsSelfLocked = new SparseIntArray();
1117
1118    private UserManagerService mUserManager;
1119
1120    private final class AppDeathRecipient implements IBinder.DeathRecipient {
1121        final ProcessRecord mApp;
1122        final int mPid;
1123        final IApplicationThread mAppThread;
1124
1125        AppDeathRecipient(ProcessRecord app, int pid,
1126                IApplicationThread thread) {
1127            if (localLOGV) Slog.v(
1128                TAG, "New death recipient " + this
1129                + " for thread " + thread.asBinder());
1130            mApp = app;
1131            mPid = pid;
1132            mAppThread = thread;
1133        }
1134
1135        @Override
1136        public void binderDied() {
1137            if (localLOGV) Slog.v(
1138                TAG, "Death received in " + this
1139                + " for thread " + mAppThread.asBinder());
1140            synchronized(ActivityManagerService.this) {
1141                appDiedLocked(mApp, mPid, mAppThread);
1142            }
1143        }
1144    }
1145
1146    static final int SHOW_ERROR_MSG = 1;
1147    static final int SHOW_NOT_RESPONDING_MSG = 2;
1148    static final int SHOW_FACTORY_ERROR_MSG = 3;
1149    static final int UPDATE_CONFIGURATION_MSG = 4;
1150    static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1151    static final int WAIT_FOR_DEBUGGER_MSG = 6;
1152    static final int SERVICE_TIMEOUT_MSG = 12;
1153    static final int UPDATE_TIME_ZONE = 13;
1154    static final int SHOW_UID_ERROR_MSG = 14;
1155    static final int IM_FEELING_LUCKY_MSG = 15;
1156    static final int PROC_START_TIMEOUT_MSG = 20;
1157    static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1158    static final int KILL_APPLICATION_MSG = 22;
1159    static final int FINALIZE_PENDING_INTENT_MSG = 23;
1160    static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1161    static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1162    static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
1163    static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1164    static final int CLEAR_DNS_CACHE_MSG = 28;
1165    static final int UPDATE_HTTP_PROXY_MSG = 29;
1166    static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
1167    static final int DISPATCH_PROCESSES_CHANGED = 31;
1168    static final int DISPATCH_PROCESS_DIED = 32;
1169    static final int REPORT_MEM_USAGE_MSG = 33;
1170    static final int REPORT_USER_SWITCH_MSG = 34;
1171    static final int CONTINUE_USER_SWITCH_MSG = 35;
1172    static final int USER_SWITCH_TIMEOUT_MSG = 36;
1173    static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1174    static final int PERSIST_URI_GRANTS_MSG = 38;
1175    static final int REQUEST_ALL_PSS_MSG = 39;
1176    static final int START_PROFILES_MSG = 40;
1177    static final int UPDATE_TIME = 41;
1178    static final int SYSTEM_USER_START_MSG = 42;
1179    static final int SYSTEM_USER_CURRENT_MSG = 43;
1180    static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1181    static final int ENABLE_SCREEN_AFTER_BOOT_MSG = 45;
1182    static final int START_USER_SWITCH_MSG = 46;
1183
1184    static final int FIRST_ACTIVITY_STACK_MSG = 100;
1185    static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1186    static final int FIRST_COMPAT_MODE_MSG = 300;
1187    static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1188
1189    AlertDialog mUidAlert;
1190    CompatModeDialog mCompatModeDialog;
1191    long mLastMemUsageReportTime = 0;
1192
1193    private LockToAppRequestDialog mLockToAppRequest;
1194
1195    /**
1196     * Flag whether the current user is a "monkey", i.e. whether
1197     * the UI is driven by a UI automation tool.
1198     */
1199    private boolean mUserIsMonkey;
1200
1201    /** Flag whether the device has a Recents UI */
1202    boolean mHasRecents;
1203
1204    /** The dimensions of the thumbnails in the Recents UI. */
1205    int mThumbnailWidth;
1206    int mThumbnailHeight;
1207
1208    final ServiceThread mHandlerThread;
1209    final MainHandler mHandler;
1210
1211    final class MainHandler extends Handler {
1212        public MainHandler(Looper looper) {
1213            super(looper, null, true);
1214        }
1215
1216        @Override
1217        public void handleMessage(Message msg) {
1218            switch (msg.what) {
1219            case SHOW_ERROR_MSG: {
1220                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1221                boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
1222                        Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
1223                synchronized (ActivityManagerService.this) {
1224                    ProcessRecord proc = (ProcessRecord)data.get("app");
1225                    AppErrorResult res = (AppErrorResult) data.get("result");
1226                    if (proc != null && proc.crashDialog != null) {
1227                        Slog.e(TAG, "App already has crash dialog: " + proc);
1228                        if (res != null) {
1229                            res.set(0);
1230                        }
1231                        return;
1232                    }
1233                    boolean isBackground = (UserHandle.getAppId(proc.uid)
1234                            >= Process.FIRST_APPLICATION_UID
1235                            && proc.pid != MY_PID);
1236                    for (int userId : mCurrentProfileIds) {
1237                        isBackground &= (proc.userId != userId);
1238                    }
1239                    if (isBackground && !showBackground) {
1240                        Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
1241                        if (res != null) {
1242                            res.set(0);
1243                        }
1244                        return;
1245                    }
1246                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1247                        Dialog d = new AppErrorDialog(mContext,
1248                                ActivityManagerService.this, res, proc);
1249                        d.show();
1250                        proc.crashDialog = d;
1251                    } else {
1252                        // The device is asleep, so just pretend that the user
1253                        // saw a crash dialog and hit "force quit".
1254                        if (res != null) {
1255                            res.set(0);
1256                        }
1257                    }
1258                }
1259
1260                ensureBootCompleted();
1261            } break;
1262            case SHOW_NOT_RESPONDING_MSG: {
1263                synchronized (ActivityManagerService.this) {
1264                    HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1265                    ProcessRecord proc = (ProcessRecord)data.get("app");
1266                    if (proc != null && proc.anrDialog != null) {
1267                        Slog.e(TAG, "App already has anr dialog: " + proc);
1268                        return;
1269                    }
1270
1271                    Intent intent = new Intent("android.intent.action.ANR");
1272                    if (!mProcessesReady) {
1273                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
1274                                | Intent.FLAG_RECEIVER_FOREGROUND);
1275                    }
1276                    broadcastIntentLocked(null, null, intent,
1277                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
1278                            false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
1279
1280                    if (mShowDialogs) {
1281                        Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
1282                                mContext, proc, (ActivityRecord)data.get("activity"),
1283                                msg.arg1 != 0);
1284                        d.show();
1285                        proc.anrDialog = d;
1286                    } else {
1287                        // Just kill the app if there is no dialog to be shown.
1288                        killAppAtUsersRequest(proc, null);
1289                    }
1290                }
1291
1292                ensureBootCompleted();
1293            } break;
1294            case SHOW_STRICT_MODE_VIOLATION_MSG: {
1295                HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1296                synchronized (ActivityManagerService.this) {
1297                    ProcessRecord proc = (ProcessRecord) data.get("app");
1298                    if (proc == null) {
1299                        Slog.e(TAG, "App not found when showing strict mode dialog.");
1300                        break;
1301                    }
1302                    if (proc.crashDialog != null) {
1303                        Slog.e(TAG, "App already has strict mode dialog: " + proc);
1304                        return;
1305                    }
1306                    AppErrorResult res = (AppErrorResult) data.get("result");
1307                    if (mShowDialogs && !mSleeping && !mShuttingDown) {
1308                        Dialog d = new StrictModeViolationDialog(mContext,
1309                                ActivityManagerService.this, res, proc);
1310                        d.show();
1311                        proc.crashDialog = d;
1312                    } else {
1313                        // The device is asleep, so just pretend that the user
1314                        // saw a crash dialog and hit "force quit".
1315                        res.set(0);
1316                    }
1317                }
1318                ensureBootCompleted();
1319            } break;
1320            case SHOW_FACTORY_ERROR_MSG: {
1321                Dialog d = new FactoryErrorDialog(
1322                    mContext, msg.getData().getCharSequence("msg"));
1323                d.show();
1324                ensureBootCompleted();
1325            } break;
1326            case UPDATE_CONFIGURATION_MSG: {
1327                final ContentResolver resolver = mContext.getContentResolver();
1328                Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1329            } break;
1330            case GC_BACKGROUND_PROCESSES_MSG: {
1331                synchronized (ActivityManagerService.this) {
1332                    performAppGcsIfAppropriateLocked();
1333                }
1334            } break;
1335            case WAIT_FOR_DEBUGGER_MSG: {
1336                synchronized (ActivityManagerService.this) {
1337                    ProcessRecord app = (ProcessRecord)msg.obj;
1338                    if (msg.arg1 != 0) {
1339                        if (!app.waitedForDebugger) {
1340                            Dialog d = new AppWaitingForDebuggerDialog(
1341                                    ActivityManagerService.this,
1342                                    mContext, app);
1343                            app.waitDialog = d;
1344                            app.waitedForDebugger = true;
1345                            d.show();
1346                        }
1347                    } else {
1348                        if (app.waitDialog != null) {
1349                            app.waitDialog.dismiss();
1350                            app.waitDialog = null;
1351                        }
1352                    }
1353                }
1354            } break;
1355            case SERVICE_TIMEOUT_MSG: {
1356                if (mDidDexOpt) {
1357                    mDidDexOpt = false;
1358                    Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1359                    nmsg.obj = msg.obj;
1360                    mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1361                    return;
1362                }
1363                mServices.serviceTimeout((ProcessRecord)msg.obj);
1364            } break;
1365            case UPDATE_TIME_ZONE: {
1366                synchronized (ActivityManagerService.this) {
1367                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1368                        ProcessRecord r = mLruProcesses.get(i);
1369                        if (r.thread != null) {
1370                            try {
1371                                r.thread.updateTimeZone();
1372                            } catch (RemoteException ex) {
1373                                Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1374                            }
1375                        }
1376                    }
1377                }
1378            } break;
1379            case CLEAR_DNS_CACHE_MSG: {
1380                synchronized (ActivityManagerService.this) {
1381                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1382                        ProcessRecord r = mLruProcesses.get(i);
1383                        if (r.thread != null) {
1384                            try {
1385                                r.thread.clearDnsCache();
1386                            } catch (RemoteException ex) {
1387                                Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1388                            }
1389                        }
1390                    }
1391                }
1392            } break;
1393            case UPDATE_HTTP_PROXY_MSG: {
1394                ProxyInfo proxy = (ProxyInfo)msg.obj;
1395                String host = "";
1396                String port = "";
1397                String exclList = "";
1398                Uri pacFileUrl = Uri.EMPTY;
1399                if (proxy != null) {
1400                    host = proxy.getHost();
1401                    port = Integer.toString(proxy.getPort());
1402                    exclList = proxy.getExclusionListAsString();
1403                    pacFileUrl = proxy.getPacFileUrl();
1404                }
1405                synchronized (ActivityManagerService.this) {
1406                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1407                        ProcessRecord r = mLruProcesses.get(i);
1408                        if (r.thread != null) {
1409                            try {
1410                                r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1411                            } catch (RemoteException ex) {
1412                                Slog.w(TAG, "Failed to update http proxy for: " +
1413                                        r.info.processName);
1414                            }
1415                        }
1416                    }
1417                }
1418            } break;
1419            case SHOW_UID_ERROR_MSG: {
1420                String title = "System UIDs Inconsistent";
1421                String text = "UIDs on the system are inconsistent, you need to wipe your"
1422                        + " data partition or your device will be unstable.";
1423                Log.e(TAG, title + ": " + text);
1424                if (mShowDialogs) {
1425                    // XXX This is a temporary dialog, no need to localize.
1426                    AlertDialog d = new BaseErrorDialog(mContext);
1427                    d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1428                    d.setCancelable(false);
1429                    d.setTitle(title);
1430                    d.setMessage(text);
1431                    d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1432                            mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1433                    mUidAlert = d;
1434                    d.show();
1435                }
1436            } break;
1437            case IM_FEELING_LUCKY_MSG: {
1438                if (mUidAlert != null) {
1439                    mUidAlert.dismiss();
1440                    mUidAlert = null;
1441                }
1442            } break;
1443            case PROC_START_TIMEOUT_MSG: {
1444                if (mDidDexOpt) {
1445                    mDidDexOpt = false;
1446                    Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1447                    nmsg.obj = msg.obj;
1448                    mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1449                    return;
1450                }
1451                ProcessRecord app = (ProcessRecord)msg.obj;
1452                synchronized (ActivityManagerService.this) {
1453                    processStartTimedOutLocked(app);
1454                }
1455            } break;
1456            case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1457                synchronized (ActivityManagerService.this) {
1458                    mStackSupervisor.doPendingActivityLaunchesLocked(true);
1459                }
1460            } break;
1461            case KILL_APPLICATION_MSG: {
1462                synchronized (ActivityManagerService.this) {
1463                    int appid = msg.arg1;
1464                    boolean restart = (msg.arg2 == 1);
1465                    Bundle bundle = (Bundle)msg.obj;
1466                    String pkg = bundle.getString("pkg");
1467                    String reason = bundle.getString("reason");
1468                    forceStopPackageLocked(pkg, appid, restart, false, true, false,
1469                            false, UserHandle.USER_ALL, reason);
1470                }
1471            } break;
1472            case FINALIZE_PENDING_INTENT_MSG: {
1473                ((PendingIntentRecord)msg.obj).completeFinalize();
1474            } break;
1475            case POST_HEAVY_NOTIFICATION_MSG: {
1476                INotificationManager inm = NotificationManager.getService();
1477                if (inm == null) {
1478                    return;
1479                }
1480
1481                ActivityRecord root = (ActivityRecord)msg.obj;
1482                ProcessRecord process = root.app;
1483                if (process == null) {
1484                    return;
1485                }
1486
1487                try {
1488                    Context context = mContext.createPackageContext(process.info.packageName, 0);
1489                    String text = mContext.getString(R.string.heavy_weight_notification,
1490                            context.getApplicationInfo().loadLabel(context.getPackageManager()));
1491                    Notification notification = new Notification();
1492                    notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1493                    notification.when = 0;
1494                    notification.flags = Notification.FLAG_ONGOING_EVENT;
1495                    notification.tickerText = text;
1496                    notification.defaults = 0; // please be quiet
1497                    notification.sound = null;
1498                    notification.vibrate = null;
1499                    notification.color = mContext.getResources().getColor(
1500                            com.android.internal.R.color.system_notification_accent_color);
1501                    notification.setLatestEventInfo(context, text,
1502                            mContext.getText(R.string.heavy_weight_notification_detail),
1503                            PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1504                                    PendingIntent.FLAG_CANCEL_CURRENT, null,
1505                                    new UserHandle(root.userId)));
1506
1507                    try {
1508                        int[] outId = new int[1];
1509                        inm.enqueueNotificationWithTag("android", "android", null,
1510                                R.string.heavy_weight_notification,
1511                                notification, outId, root.userId);
1512                    } catch (RuntimeException e) {
1513                        Slog.w(ActivityManagerService.TAG,
1514                                "Error showing notification for heavy-weight app", e);
1515                    } catch (RemoteException e) {
1516                    }
1517                } catch (NameNotFoundException e) {
1518                    Slog.w(TAG, "Unable to create context for heavy notification", e);
1519                }
1520            } break;
1521            case CANCEL_HEAVY_NOTIFICATION_MSG: {
1522                INotificationManager inm = NotificationManager.getService();
1523                if (inm == null) {
1524                    return;
1525                }
1526                try {
1527                    inm.cancelNotificationWithTag("android", null,
1528                            R.string.heavy_weight_notification,  msg.arg1);
1529                } catch (RuntimeException e) {
1530                    Slog.w(ActivityManagerService.TAG,
1531                            "Error canceling notification for service", e);
1532                } catch (RemoteException e) {
1533                }
1534            } break;
1535            case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1536                synchronized (ActivityManagerService.this) {
1537                    checkExcessivePowerUsageLocked(true);
1538                    removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1539                    Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1540                    sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1541                }
1542            } break;
1543            case SHOW_COMPAT_MODE_DIALOG_MSG: {
1544                synchronized (ActivityManagerService.this) {
1545                    ActivityRecord ar = (ActivityRecord)msg.obj;
1546                    if (mCompatModeDialog != null) {
1547                        if (mCompatModeDialog.mAppInfo.packageName.equals(
1548                                ar.info.applicationInfo.packageName)) {
1549                            return;
1550                        }
1551                        mCompatModeDialog.dismiss();
1552                        mCompatModeDialog = null;
1553                    }
1554                    if (ar != null && false) {
1555                        if (mCompatModePackages.getPackageAskCompatModeLocked(
1556                                ar.packageName)) {
1557                            int mode = mCompatModePackages.computeCompatModeLocked(
1558                                    ar.info.applicationInfo);
1559                            if (mode == ActivityManager.COMPAT_MODE_DISABLED
1560                                    || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1561                                mCompatModeDialog = new CompatModeDialog(
1562                                        ActivityManagerService.this, mContext,
1563                                        ar.info.applicationInfo);
1564                                mCompatModeDialog.show();
1565                            }
1566                        }
1567                    }
1568                }
1569                break;
1570            }
1571            case DISPATCH_PROCESSES_CHANGED: {
1572                dispatchProcessesChanged();
1573                break;
1574            }
1575            case DISPATCH_PROCESS_DIED: {
1576                final int pid = msg.arg1;
1577                final int uid = msg.arg2;
1578                dispatchProcessDied(pid, uid);
1579                break;
1580            }
1581            case REPORT_MEM_USAGE_MSG: {
1582                final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1583                Thread thread = new Thread() {
1584                    @Override public void run() {
1585                        final SparseArray<ProcessMemInfo> infoMap
1586                                = new SparseArray<ProcessMemInfo>(memInfos.size());
1587                        for (int i=0, N=memInfos.size(); i<N; i++) {
1588                            ProcessMemInfo mi = memInfos.get(i);
1589                            infoMap.put(mi.pid, mi);
1590                        }
1591                        updateCpuStatsNow();
1592                        synchronized (mProcessCpuThread) {
1593                            final int N = mProcessCpuTracker.countStats();
1594                            for (int i=0; i<N; i++) {
1595                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
1596                                if (st.vsize > 0) {
1597                                    long pss = Debug.getPss(st.pid, null);
1598                                    if (pss > 0) {
1599                                        if (infoMap.indexOfKey(st.pid) < 0) {
1600                                            ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
1601                                                    ProcessList.NATIVE_ADJ, -1, "native", null);
1602                                            mi.pss = pss;
1603                                            memInfos.add(mi);
1604                                        }
1605                                    }
1606                                }
1607                            }
1608                        }
1609
1610                        long totalPss = 0;
1611                        for (int i=0, N=memInfos.size(); i<N; i++) {
1612                            ProcessMemInfo mi = memInfos.get(i);
1613                            if (mi.pss == 0) {
1614                                mi.pss = Debug.getPss(mi.pid, null);
1615                            }
1616                            totalPss += mi.pss;
1617                        }
1618                        Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
1619                            @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
1620                                if (lhs.oomAdj != rhs.oomAdj) {
1621                                    return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
1622                                }
1623                                if (lhs.pss != rhs.pss) {
1624                                    return lhs.pss < rhs.pss ? 1 : -1;
1625                                }
1626                                return 0;
1627                            }
1628                        });
1629
1630                        StringBuilder tag = new StringBuilder(128);
1631                        StringBuilder stack = new StringBuilder(128);
1632                        tag.append("Low on memory -- ");
1633                        appendMemBucket(tag, totalPss, "total", false);
1634                        appendMemBucket(stack, totalPss, "total", true);
1635
1636                        StringBuilder logBuilder = new StringBuilder(1024);
1637                        logBuilder.append("Low on memory:\n");
1638
1639                        boolean firstLine = true;
1640                        int lastOomAdj = Integer.MIN_VALUE;
1641                        for (int i=0, N=memInfos.size(); i<N; i++) {
1642                            ProcessMemInfo mi = memInfos.get(i);
1643
1644                            if (mi.oomAdj != ProcessList.NATIVE_ADJ
1645                                    && (mi.oomAdj < ProcessList.SERVICE_ADJ
1646                                            || mi.oomAdj == ProcessList.HOME_APP_ADJ
1647                                            || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
1648                                if (lastOomAdj != mi.oomAdj) {
1649                                    lastOomAdj = mi.oomAdj;
1650                                    if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1651                                        tag.append(" / ");
1652                                    }
1653                                    if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
1654                                        if (firstLine) {
1655                                            stack.append(":");
1656                                            firstLine = false;
1657                                        }
1658                                        stack.append("\n\t at ");
1659                                    } else {
1660                                        stack.append("$");
1661                                    }
1662                                } else {
1663                                    tag.append(" ");
1664                                    stack.append("$");
1665                                }
1666                                if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
1667                                    appendMemBucket(tag, mi.pss, mi.name, false);
1668                                }
1669                                appendMemBucket(stack, mi.pss, mi.name, true);
1670                                if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
1671                                        && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
1672                                    stack.append("(");
1673                                    for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
1674                                        if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
1675                                            stack.append(DUMP_MEM_OOM_LABEL[k]);
1676                                            stack.append(":");
1677                                            stack.append(DUMP_MEM_OOM_ADJ[k]);
1678                                        }
1679                                    }
1680                                    stack.append(")");
1681                                }
1682                            }
1683
1684                            logBuilder.append("  ");
1685                            logBuilder.append(ProcessList.makeOomAdjString(mi.oomAdj));
1686                            logBuilder.append(' ');
1687                            logBuilder.append(ProcessList.makeProcStateString(mi.procState));
1688                            logBuilder.append(' ');
1689                            ProcessList.appendRamKb(logBuilder, mi.pss);
1690                            logBuilder.append(" kB: ");
1691                            logBuilder.append(mi.name);
1692                            logBuilder.append(" (");
1693                            logBuilder.append(mi.pid);
1694                            logBuilder.append(") ");
1695                            logBuilder.append(mi.adjType);
1696                            logBuilder.append('\n');
1697                            if (mi.adjReason != null) {
1698                                logBuilder.append("                      ");
1699                                logBuilder.append(mi.adjReason);
1700                                logBuilder.append('\n');
1701                            }
1702                        }
1703
1704                        logBuilder.append("           ");
1705                        ProcessList.appendRamKb(logBuilder, totalPss);
1706                        logBuilder.append(" kB: TOTAL\n");
1707
1708                        long[] infos = new long[Debug.MEMINFO_COUNT];
1709                        Debug.getMemInfo(infos);
1710                        logBuilder.append("  MemInfo: ");
1711                        logBuilder.append(infos[Debug.MEMINFO_SLAB]).append(" kB slab, ");
1712                        logBuilder.append(infos[Debug.MEMINFO_SHMEM]).append(" kB shmem, ");
1713                        logBuilder.append(infos[Debug.MEMINFO_BUFFERS]).append(" kB buffers, ");
1714                        logBuilder.append(infos[Debug.MEMINFO_CACHED]).append(" kB cached, ");
1715                        logBuilder.append(infos[Debug.MEMINFO_FREE]).append(" kB free\n");
1716                        if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
1717                            logBuilder.append("  ZRAM: ");
1718                            logBuilder.append(infos[Debug.MEMINFO_ZRAM_TOTAL]);
1719                            logBuilder.append(" kB RAM, ");
1720                            logBuilder.append(infos[Debug.MEMINFO_SWAP_TOTAL]);
1721                            logBuilder.append(" kB swap total, ");
1722                            logBuilder.append(infos[Debug.MEMINFO_SWAP_FREE]);
1723                            logBuilder.append(" kB swap free\n");
1724                        }
1725                        Slog.i(TAG, logBuilder.toString());
1726
1727                        StringBuilder dropBuilder = new StringBuilder(1024);
1728                        /*
1729                        StringWriter oomSw = new StringWriter();
1730                        PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
1731                        StringWriter catSw = new StringWriter();
1732                        PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1733                        String[] emptyArgs = new String[] { };
1734                        dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
1735                        oomPw.flush();
1736                        String oomString = oomSw.toString();
1737                        */
1738                        dropBuilder.append(stack);
1739                        dropBuilder.append('\n');
1740                        dropBuilder.append('\n');
1741                        dropBuilder.append(logBuilder);
1742                        dropBuilder.append('\n');
1743                        /*
1744                        dropBuilder.append(oomString);
1745                        dropBuilder.append('\n');
1746                        */
1747                        StringWriter catSw = new StringWriter();
1748                        synchronized (ActivityManagerService.this) {
1749                            PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
1750                            String[] emptyArgs = new String[] { };
1751                            catPw.println();
1752                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
1753                            catPw.println();
1754                            mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1755                                    false, false, null);
1756                            catPw.println();
1757                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
1758                            catPw.flush();
1759                        }
1760                        dropBuilder.append(catSw.toString());
1761                        addErrorToDropBox("lowmem", null, "system_server", null,
1762                                null, tag.toString(), dropBuilder.toString(), null, null);
1763                        //Slog.i(TAG, "Sent to dropbox:");
1764                        //Slog.i(TAG, dropBuilder.toString());
1765                        synchronized (ActivityManagerService.this) {
1766                            long now = SystemClock.uptimeMillis();
1767                            if (mLastMemUsageReportTime < now) {
1768                                mLastMemUsageReportTime = now;
1769                            }
1770                        }
1771                    }
1772                };
1773                thread.start();
1774                break;
1775            }
1776            case START_USER_SWITCH_MSG: {
1777                showUserSwitchDialog(msg.arg1, (String) msg.obj);
1778                break;
1779            }
1780            case REPORT_USER_SWITCH_MSG: {
1781                dispatchUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1782                break;
1783            }
1784            case CONTINUE_USER_SWITCH_MSG: {
1785                continueUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1786                break;
1787            }
1788            case USER_SWITCH_TIMEOUT_MSG: {
1789                timeoutUserSwitch((UserStartedState) msg.obj, msg.arg1, msg.arg2);
1790                break;
1791            }
1792            case IMMERSIVE_MODE_LOCK_MSG: {
1793                final boolean nextState = (msg.arg1 != 0);
1794                if (mUpdateLock.isHeld() != nextState) {
1795                    if (DEBUG_IMMERSIVE) {
1796                        final ActivityRecord r = (ActivityRecord) msg.obj;
1797                        Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1798                    }
1799                    if (nextState) {
1800                        mUpdateLock.acquire();
1801                    } else {
1802                        mUpdateLock.release();
1803                    }
1804                }
1805                break;
1806            }
1807            case PERSIST_URI_GRANTS_MSG: {
1808                writeGrantedUriPermissions();
1809                break;
1810            }
1811            case REQUEST_ALL_PSS_MSG: {
1812                requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1813                break;
1814            }
1815            case START_PROFILES_MSG: {
1816                synchronized (ActivityManagerService.this) {
1817                    startProfilesLocked();
1818                }
1819                break;
1820            }
1821            case UPDATE_TIME: {
1822                synchronized (ActivityManagerService.this) {
1823                    for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1824                        ProcessRecord r = mLruProcesses.get(i);
1825                        if (r.thread != null) {
1826                            try {
1827                                r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1828                            } catch (RemoteException ex) {
1829                                Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1830                            }
1831                        }
1832                    }
1833                }
1834                break;
1835            }
1836            case SYSTEM_USER_START_MSG: {
1837                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1838                        Integer.toString(msg.arg1), msg.arg1);
1839                mSystemServiceManager.startUser(msg.arg1);
1840                break;
1841            }
1842            case SYSTEM_USER_CURRENT_MSG: {
1843                mBatteryStatsService.noteEvent(
1844                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1845                        Integer.toString(msg.arg2), msg.arg2);
1846                mBatteryStatsService.noteEvent(
1847                        BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1848                        Integer.toString(msg.arg1), msg.arg1);
1849                mSystemServiceManager.switchUser(msg.arg1);
1850                mLockToAppRequest.clearPrompt();
1851                break;
1852            }
1853            case ENTER_ANIMATION_COMPLETE_MSG: {
1854                synchronized (ActivityManagerService.this) {
1855                    ActivityRecord r = ActivityRecord.forToken((IBinder) msg.obj);
1856                    if (r != null && r.app != null && r.app.thread != null) {
1857                        try {
1858                            r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1859                        } catch (RemoteException e) {
1860                        }
1861                    }
1862                }
1863                break;
1864            }
1865            case ENABLE_SCREEN_AFTER_BOOT_MSG: {
1866                enableScreenAfterBoot();
1867                break;
1868            }
1869            }
1870        }
1871    };
1872
1873    static final int COLLECT_PSS_BG_MSG = 1;
1874
1875    final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
1876        @Override
1877        public void handleMessage(Message msg) {
1878            switch (msg.what) {
1879            case COLLECT_PSS_BG_MSG: {
1880                long start = SystemClock.uptimeMillis();
1881                MemInfoReader memInfo = null;
1882                synchronized (ActivityManagerService.this) {
1883                    if (mFullPssPending) {
1884                        mFullPssPending = false;
1885                        memInfo = new MemInfoReader();
1886                    }
1887                }
1888                if (memInfo != null) {
1889                    updateCpuStatsNow();
1890                    long nativeTotalPss = 0;
1891                    synchronized (mProcessCpuThread) {
1892                        final int N = mProcessCpuTracker.countStats();
1893                        for (int j=0; j<N; j++) {
1894                            ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
1895                            if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
1896                                // This is definitely an application process; skip it.
1897                                continue;
1898                            }
1899                            synchronized (mPidsSelfLocked) {
1900                                if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
1901                                    // This is one of our own processes; skip it.
1902                                    continue;
1903                                }
1904                            }
1905                            nativeTotalPss += Debug.getPss(st.pid, null);
1906                        }
1907                    }
1908                    memInfo.readMemInfo();
1909                    synchronized (this) {
1910                        if (DEBUG_PSS) Slog.d(TAG, "Collected native and kernel memory in "
1911                                + (SystemClock.uptimeMillis()-start) + "ms");
1912                        mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
1913                                memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
1914                                memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()
1915                                        +memInfo.getSlabSizeKb(),
1916                                nativeTotalPss);
1917                    }
1918                }
1919
1920                int i=0, num=0;
1921                long[] tmp = new long[1];
1922                do {
1923                    ProcessRecord proc;
1924                    int procState;
1925                    int pid;
1926                    synchronized (ActivityManagerService.this) {
1927                        if (i >= mPendingPssProcesses.size()) {
1928                            if (DEBUG_PSS) Slog.d(TAG, "Collected PSS of " + num + " of " + i
1929                                    + " processes in " + (SystemClock.uptimeMillis()-start) + "ms");
1930                            mPendingPssProcesses.clear();
1931                            return;
1932                        }
1933                        proc = mPendingPssProcesses.get(i);
1934                        procState = proc.pssProcState;
1935                        if (proc.thread != null && procState == proc.setProcState) {
1936                            pid = proc.pid;
1937                        } else {
1938                            proc = null;
1939                            pid = 0;
1940                        }
1941                        i++;
1942                    }
1943                    if (proc != null) {
1944                        long pss = Debug.getPss(pid, tmp);
1945                        synchronized (ActivityManagerService.this) {
1946                            if (proc.thread != null && proc.setProcState == procState
1947                                    && proc.pid == pid) {
1948                                num++;
1949                                proc.lastPssTime = SystemClock.uptimeMillis();
1950                                proc.baseProcessTracker.addPss(pss, tmp[0], true, proc.pkgList);
1951                                if (DEBUG_PSS) Slog.d(TAG, "PSS of " + proc.toShortString()
1952                                        + ": " + pss + " lastPss=" + proc.lastPss
1953                                        + " state=" + ProcessList.makeProcStateString(procState));
1954                                if (proc.initialIdlePss == 0) {
1955                                    proc.initialIdlePss = pss;
1956                                }
1957                                proc.lastPss = pss;
1958                                if (procState >= ActivityManager.PROCESS_STATE_HOME) {
1959                                    proc.lastCachedPss = pss;
1960                                }
1961                            }
1962                        }
1963                    }
1964                } while (true);
1965            }
1966            }
1967        }
1968    };
1969
1970    /**
1971     * Monitor for package changes and update our internal state.
1972     */
1973    private final PackageMonitor mPackageMonitor = new PackageMonitor() {
1974        @Override
1975        public void onPackageRemoved(String packageName, int uid) {
1976            // Remove all tasks with activities in the specified package from the list of recent tasks
1977            synchronized (ActivityManagerService.this) {
1978                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
1979                    TaskRecord tr = mRecentTasks.get(i);
1980                    ComponentName cn = tr.intent.getComponent();
1981                    if (cn != null && cn.getPackageName().equals(packageName)) {
1982                        // If the package name matches, remove the task and kill the process
1983                        removeTaskByIdLocked(tr.taskId, ActivityManager.REMOVE_TASK_KILL_PROCESS);
1984                    }
1985                }
1986            }
1987        }
1988
1989        @Override
1990        public boolean onPackageChanged(String packageName, int uid, String[] components) {
1991            onPackageModified(packageName);
1992            return true;
1993        }
1994
1995        @Override
1996        public void onPackageModified(String packageName) {
1997            final PackageManager pm = mContext.getPackageManager();
1998            final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
1999                    new ArrayList<Pair<Intent, Integer>>();
2000            final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
2001            // Copy the list of recent tasks so that we don't hold onto the lock on
2002            // ActivityManagerService for long periods while checking if components exist.
2003            synchronized (ActivityManagerService.this) {
2004                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
2005                    TaskRecord tr = mRecentTasks.get(i);
2006                    recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
2007                }
2008            }
2009            // Check the recent tasks and filter out all tasks with components that no longer exist.
2010            Intent tmpI = new Intent();
2011            for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
2012                Pair<Intent, Integer> p = recentTaskIntents.get(i);
2013                ComponentName cn = p.first.getComponent();
2014                if (cn != null && cn.getPackageName().equals(packageName)) {
2015                    try {
2016                        // Add the task to the list to remove if the component no longer exists
2017                        tmpI.setComponent(cn);
2018                        if (pm.queryIntentActivities(tmpI, PackageManager.MATCH_DEFAULT_ONLY).isEmpty()) {
2019                            tasksToRemove.add(p.second);
2020                        }
2021                    } catch (Exception e) {}
2022                }
2023            }
2024            // Prune all the tasks with removed components from the list of recent tasks
2025            synchronized (ActivityManagerService.this) {
2026                for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
2027                    // Remove the task but don't kill the process (since other components in that
2028                    // package may still be running and in the background)
2029                    removeTaskByIdLocked(tasksToRemove.get(i), 0);
2030                }
2031            }
2032        }
2033
2034        @Override
2035        public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
2036            // Force stop the specified packages
2037            if (packages != null) {
2038                for (String pkg : packages) {
2039                    synchronized (ActivityManagerService.this) {
2040                        if (forceStopPackageLocked(pkg, -1, false, false, false, false, false, 0,
2041                                "finished booting")) {
2042                            return true;
2043                        }
2044                    }
2045                }
2046            }
2047            return false;
2048        }
2049    };
2050
2051    public void setSystemProcess() {
2052        try {
2053            ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2054            ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2055            ServiceManager.addService("meminfo", new MemBinder(this));
2056            ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2057            ServiceManager.addService("dbinfo", new DbBinder(this));
2058            if (MONITOR_CPU_USAGE) {
2059                ServiceManager.addService("cpuinfo", new CpuBinder(this));
2060            }
2061            ServiceManager.addService("permission", new PermissionController(this));
2062
2063            ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2064                    "android", STOCK_PM_FLAGS);
2065            mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2066
2067            synchronized (this) {
2068                ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2069                app.persistent = true;
2070                app.pid = MY_PID;
2071                app.maxAdj = ProcessList.SYSTEM_ADJ;
2072                app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2073                mProcessNames.put(app.processName, app.uid, app);
2074                synchronized (mPidsSelfLocked) {
2075                    mPidsSelfLocked.put(app.pid, app);
2076                }
2077                updateLruProcessLocked(app, false, null);
2078                updateOomAdjLocked();
2079            }
2080        } catch (PackageManager.NameNotFoundException e) {
2081            throw new RuntimeException(
2082                    "Unable to find android system package", e);
2083        }
2084    }
2085
2086    public void setWindowManager(WindowManagerService wm) {
2087        mWindowManager = wm;
2088        mStackSupervisor.setWindowManager(wm);
2089    }
2090
2091    public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2092        mUsageStatsService = usageStatsManager;
2093    }
2094
2095    public void startObservingNativeCrashes() {
2096        final NativeCrashListener ncl = new NativeCrashListener(this);
2097        ncl.start();
2098    }
2099
2100    public IAppOpsService getAppOpsService() {
2101        return mAppOpsService;
2102    }
2103
2104    static class MemBinder extends Binder {
2105        ActivityManagerService mActivityManagerService;
2106        MemBinder(ActivityManagerService activityManagerService) {
2107            mActivityManagerService = activityManagerService;
2108        }
2109
2110        @Override
2111        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2112            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2113                    != PackageManager.PERMISSION_GRANTED) {
2114                pw.println("Permission Denial: can't dump meminfo from from pid="
2115                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2116                        + " without permission " + android.Manifest.permission.DUMP);
2117                return;
2118            }
2119
2120            mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2121        }
2122    }
2123
2124    static class GraphicsBinder extends Binder {
2125        ActivityManagerService mActivityManagerService;
2126        GraphicsBinder(ActivityManagerService activityManagerService) {
2127            mActivityManagerService = activityManagerService;
2128        }
2129
2130        @Override
2131        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2132            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2133                    != PackageManager.PERMISSION_GRANTED) {
2134                pw.println("Permission Denial: can't dump gfxinfo from from pid="
2135                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2136                        + " without permission " + android.Manifest.permission.DUMP);
2137                return;
2138            }
2139
2140            mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2141        }
2142    }
2143
2144    static class DbBinder extends Binder {
2145        ActivityManagerService mActivityManagerService;
2146        DbBinder(ActivityManagerService activityManagerService) {
2147            mActivityManagerService = activityManagerService;
2148        }
2149
2150        @Override
2151        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2152            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2153                    != PackageManager.PERMISSION_GRANTED) {
2154                pw.println("Permission Denial: can't dump dbinfo from from pid="
2155                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2156                        + " without permission " + android.Manifest.permission.DUMP);
2157                return;
2158            }
2159
2160            mActivityManagerService.dumpDbInfo(fd, pw, args);
2161        }
2162    }
2163
2164    static class CpuBinder extends Binder {
2165        ActivityManagerService mActivityManagerService;
2166        CpuBinder(ActivityManagerService activityManagerService) {
2167            mActivityManagerService = activityManagerService;
2168        }
2169
2170        @Override
2171        protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2172            if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2173                    != PackageManager.PERMISSION_GRANTED) {
2174                pw.println("Permission Denial: can't dump cpuinfo from from pid="
2175                        + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2176                        + " without permission " + android.Manifest.permission.DUMP);
2177                return;
2178            }
2179
2180            synchronized (mActivityManagerService.mProcessCpuThread) {
2181                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2182                pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2183                        SystemClock.uptimeMillis()));
2184            }
2185        }
2186    }
2187
2188    public static final class Lifecycle extends SystemService {
2189        private final ActivityManagerService mService;
2190
2191        public Lifecycle(Context context) {
2192            super(context);
2193            mService = new ActivityManagerService(context);
2194        }
2195
2196        @Override
2197        public void onStart() {
2198            mService.start();
2199        }
2200
2201        public ActivityManagerService getService() {
2202            return mService;
2203        }
2204    }
2205
2206    // Note: This method is invoked on the main thread but may need to attach various
2207    // handlers to other threads.  So take care to be explicit about the looper.
2208    public ActivityManagerService(Context systemContext) {
2209        mContext = systemContext;
2210        mFactoryTest = FactoryTest.getMode();
2211        mSystemThread = ActivityThread.currentActivityThread();
2212
2213        Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2214
2215        mHandlerThread = new ServiceThread(TAG,
2216                android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2217        mHandlerThread.start();
2218        mHandler = new MainHandler(mHandlerThread.getLooper());
2219
2220        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2221                "foreground", BROADCAST_FG_TIMEOUT, false);
2222        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2223                "background", BROADCAST_BG_TIMEOUT, true);
2224        mBroadcastQueues[0] = mFgBroadcastQueue;
2225        mBroadcastQueues[1] = mBgBroadcastQueue;
2226
2227        mServices = new ActiveServices(this);
2228        mProviderMap = new ProviderMap(this);
2229
2230        // TODO: Move creation of battery stats service outside of activity manager service.
2231        File dataDir = Environment.getDataDirectory();
2232        File systemDir = new File(dataDir, "system");
2233        systemDir.mkdirs();
2234        mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2235        mBatteryStatsService.getActiveStatistics().readLocked();
2236        mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2237        mOnBattery = DEBUG_POWER ? true
2238                : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2239        mBatteryStatsService.getActiveStatistics().setCallback(this);
2240
2241        mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2242
2243        mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2244
2245        mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2246
2247        // User 0 is the first and only user that runs at boot.
2248        mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
2249        mUserLru.add(Integer.valueOf(0));
2250        updateStartedUserArrayLocked();
2251
2252        GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2253            ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2254
2255        mConfiguration.setToDefaults();
2256        mConfiguration.setLocale(Locale.getDefault());
2257
2258        mConfigurationSeq = mConfiguration.seq = 1;
2259        mProcessCpuTracker.init();
2260
2261        mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2262        mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2263        mStackSupervisor = new ActivityStackSupervisor(this);
2264        mTaskPersister = new TaskPersister(systemDir, mStackSupervisor);
2265
2266        mProcessCpuThread = new Thread("CpuTracker") {
2267            @Override
2268            public void run() {
2269                while (true) {
2270                    try {
2271                        try {
2272                            synchronized(this) {
2273                                final long now = SystemClock.uptimeMillis();
2274                                long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2275                                long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2276                                //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2277                                //        + ", write delay=" + nextWriteDelay);
2278                                if (nextWriteDelay < nextCpuDelay) {
2279                                    nextCpuDelay = nextWriteDelay;
2280                                }
2281                                if (nextCpuDelay > 0) {
2282                                    mProcessCpuMutexFree.set(true);
2283                                    this.wait(nextCpuDelay);
2284                                }
2285                            }
2286                        } catch (InterruptedException e) {
2287                        }
2288                        updateCpuStatsNow();
2289                    } catch (Exception e) {
2290                        Slog.e(TAG, "Unexpected exception collecting process stats", e);
2291                    }
2292                }
2293            }
2294        };
2295
2296        mLockToAppRequest = new LockToAppRequestDialog(mContext, this);
2297
2298        Watchdog.getInstance().addMonitor(this);
2299        Watchdog.getInstance().addThread(mHandler);
2300    }
2301
2302    public void setSystemServiceManager(SystemServiceManager mgr) {
2303        mSystemServiceManager = mgr;
2304    }
2305
2306    private void start() {
2307        Process.removeAllProcessGroups();
2308        mProcessCpuThread.start();
2309
2310        mBatteryStatsService.publish(mContext);
2311        mAppOpsService.publish(mContext);
2312        Slog.d("AppOps", "AppOpsService published");
2313        LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2314    }
2315
2316    public void initPowerManagement() {
2317        mStackSupervisor.initPowerManagement();
2318        mBatteryStatsService.initPowerManagement();
2319    }
2320
2321    @Override
2322    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2323            throws RemoteException {
2324        if (code == SYSPROPS_TRANSACTION) {
2325            // We need to tell all apps about the system property change.
2326            ArrayList<IBinder> procs = new ArrayList<IBinder>();
2327            synchronized(this) {
2328                final int NP = mProcessNames.getMap().size();
2329                for (int ip=0; ip<NP; ip++) {
2330                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2331                    final int NA = apps.size();
2332                    for (int ia=0; ia<NA; ia++) {
2333                        ProcessRecord app = apps.valueAt(ia);
2334                        if (app.thread != null) {
2335                            procs.add(app.thread.asBinder());
2336                        }
2337                    }
2338                }
2339            }
2340
2341            int N = procs.size();
2342            for (int i=0; i<N; i++) {
2343                Parcel data2 = Parcel.obtain();
2344                try {
2345                    procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2346                } catch (RemoteException e) {
2347                }
2348                data2.recycle();
2349            }
2350        }
2351        try {
2352            return super.onTransact(code, data, reply, flags);
2353        } catch (RuntimeException e) {
2354            // The activity manager only throws security exceptions, so let's
2355            // log all others.
2356            if (!(e instanceof SecurityException)) {
2357                Slog.wtf(TAG, "Activity Manager Crash", e);
2358            }
2359            throw e;
2360        }
2361    }
2362
2363    void updateCpuStats() {
2364        final long now = SystemClock.uptimeMillis();
2365        if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2366            return;
2367        }
2368        if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2369            synchronized (mProcessCpuThread) {
2370                mProcessCpuThread.notify();
2371            }
2372        }
2373    }
2374
2375    void updateCpuStatsNow() {
2376        synchronized (mProcessCpuThread) {
2377            mProcessCpuMutexFree.set(false);
2378            final long now = SystemClock.uptimeMillis();
2379            boolean haveNewCpuStats = false;
2380
2381            if (MONITOR_CPU_USAGE &&
2382                    mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2383                mLastCpuTime.set(now);
2384                haveNewCpuStats = true;
2385                mProcessCpuTracker.update();
2386                //Slog.i(TAG, mProcessCpu.printCurrentState());
2387                //Slog.i(TAG, "Total CPU usage: "
2388                //        + mProcessCpu.getTotalCpuPercent() + "%");
2389
2390                // Slog the cpu usage if the property is set.
2391                if ("true".equals(SystemProperties.get("events.cpu"))) {
2392                    int user = mProcessCpuTracker.getLastUserTime();
2393                    int system = mProcessCpuTracker.getLastSystemTime();
2394                    int iowait = mProcessCpuTracker.getLastIoWaitTime();
2395                    int irq = mProcessCpuTracker.getLastIrqTime();
2396                    int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2397                    int idle = mProcessCpuTracker.getLastIdleTime();
2398
2399                    int total = user + system + iowait + irq + softIrq + idle;
2400                    if (total == 0) total = 1;
2401
2402                    EventLog.writeEvent(EventLogTags.CPU,
2403                            ((user+system+iowait+irq+softIrq) * 100) / total,
2404                            (user * 100) / total,
2405                            (system * 100) / total,
2406                            (iowait * 100) / total,
2407                            (irq * 100) / total,
2408                            (softIrq * 100) / total);
2409                }
2410            }
2411
2412            long[] cpuSpeedTimes = mProcessCpuTracker.getLastCpuSpeedTimes();
2413            final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2414            synchronized(bstats) {
2415                synchronized(mPidsSelfLocked) {
2416                    if (haveNewCpuStats) {
2417                        if (mOnBattery) {
2418                            int perc = bstats.startAddingCpuLocked();
2419                            int totalUTime = 0;
2420                            int totalSTime = 0;
2421                            final int N = mProcessCpuTracker.countStats();
2422                            for (int i=0; i<N; i++) {
2423                                ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2424                                if (!st.working) {
2425                                    continue;
2426                                }
2427                                ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2428                                int otherUTime = (st.rel_utime*perc)/100;
2429                                int otherSTime = (st.rel_stime*perc)/100;
2430                                totalUTime += otherUTime;
2431                                totalSTime += otherSTime;
2432                                if (pr != null) {
2433                                    BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2434                                    if (ps == null || !ps.isActive()) {
2435                                        pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2436                                                pr.info.uid, pr.processName);
2437                                    }
2438                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2439                                            st.rel_stime-otherSTime);
2440                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2441                                    pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
2442                                } else {
2443                                    BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2444                                    if (ps == null || !ps.isActive()) {
2445                                        st.batteryStats = ps = bstats.getProcessStatsLocked(
2446                                                bstats.mapUid(st.uid), st.name);
2447                                    }
2448                                    ps.addCpuTimeLocked(st.rel_utime-otherUTime,
2449                                            st.rel_stime-otherSTime);
2450                                    ps.addSpeedStepTimes(cpuSpeedTimes);
2451                                }
2452                            }
2453                            bstats.finishAddingCpuLocked(perc, totalUTime,
2454                                    totalSTime, cpuSpeedTimes);
2455                        }
2456                    }
2457                }
2458
2459                if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2460                    mLastWriteTime = now;
2461                    mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
2462                }
2463            }
2464        }
2465    }
2466
2467    @Override
2468    public void batteryNeedsCpuUpdate() {
2469        updateCpuStatsNow();
2470    }
2471
2472    @Override
2473    public void batteryPowerChanged(boolean onBattery) {
2474        // When plugging in, update the CPU stats first before changing
2475        // the plug state.
2476        updateCpuStatsNow();
2477        synchronized (this) {
2478            synchronized(mPidsSelfLocked) {
2479                mOnBattery = DEBUG_POWER ? true : onBattery;
2480            }
2481        }
2482    }
2483
2484    /**
2485     * Initialize the application bind args. These are passed to each
2486     * process when the bindApplication() IPC is sent to the process. They're
2487     * lazily setup to make sure the services are running when they're asked for.
2488     */
2489    private HashMap<String, IBinder> getCommonServicesLocked() {
2490        if (mAppBindArgs == null) {
2491            mAppBindArgs = new HashMap<String, IBinder>();
2492
2493            // Setup the application init args
2494            mAppBindArgs.put("package", ServiceManager.getService("package"));
2495            mAppBindArgs.put("window", ServiceManager.getService("window"));
2496            mAppBindArgs.put(Context.ALARM_SERVICE,
2497                    ServiceManager.getService(Context.ALARM_SERVICE));
2498        }
2499        return mAppBindArgs;
2500    }
2501
2502    final void setFocusedActivityLocked(ActivityRecord r) {
2503        if (mFocusedActivity != r) {
2504            if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedActivityLocked: r=" + r);
2505            mFocusedActivity = r;
2506            if (r.task != null && r.task.voiceInteractor != null) {
2507                startRunningVoiceLocked();
2508            } else {
2509                finishRunningVoiceLocked();
2510            }
2511            mStackSupervisor.setFocusedStack(r);
2512            if (r != null) {
2513                mWindowManager.setFocusedApp(r.appToken, true);
2514            }
2515            applyUpdateLockStateLocked(r);
2516        }
2517    }
2518
2519    final void clearFocusedActivity(ActivityRecord r) {
2520        if (mFocusedActivity == r) {
2521            mFocusedActivity = null;
2522        }
2523    }
2524
2525    @Override
2526    public void setFocusedStack(int stackId) {
2527        if (DEBUG_FOCUS) Slog.d(TAG, "setFocusedStack: stackId=" + stackId);
2528        synchronized (ActivityManagerService.this) {
2529            ActivityStack stack = mStackSupervisor.getStack(stackId);
2530            if (stack != null) {
2531                ActivityRecord r = stack.topRunningActivityLocked(null);
2532                if (r != null) {
2533                    setFocusedActivityLocked(r);
2534                }
2535            }
2536        }
2537    }
2538
2539    @Override
2540    public void notifyActivityDrawn(IBinder token) {
2541        if (DEBUG_VISBILITY) Slog.d(TAG, "notifyActivityDrawn: token=" + token);
2542        synchronized (this) {
2543            ActivityRecord r= mStackSupervisor.isInAnyStackLocked(token);
2544            if (r != null) {
2545                r.task.stack.notifyActivityDrawnLocked(r);
2546            }
2547        }
2548    }
2549
2550    final void applyUpdateLockStateLocked(ActivityRecord r) {
2551        // Modifications to the UpdateLock state are done on our handler, outside
2552        // the activity manager's locks.  The new state is determined based on the
2553        // state *now* of the relevant activity record.  The object is passed to
2554        // the handler solely for logging detail, not to be consulted/modified.
2555        final boolean nextState = r != null && r.immersive;
2556        mHandler.sendMessage(
2557                mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2558    }
2559
2560    final void showAskCompatModeDialogLocked(ActivityRecord r) {
2561        Message msg = Message.obtain();
2562        msg.what = SHOW_COMPAT_MODE_DIALOG_MSG;
2563        msg.obj = r.task.askedCompatMode ? null : r;
2564        mHandler.sendMessage(msg);
2565    }
2566
2567    private final int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2568            String what, Object obj, ProcessRecord srcApp) {
2569        app.lastActivityTime = now;
2570
2571        if (app.activities.size() > 0) {
2572            // Don't want to touch dependent processes that are hosting activities.
2573            return index;
2574        }
2575
2576        int lrui = mLruProcesses.lastIndexOf(app);
2577        if (lrui < 0) {
2578            Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2579                    + what + " " + obj + " from " + srcApp);
2580            return index;
2581        }
2582
2583        if (lrui >= index) {
2584            // Don't want to cause this to move dependent processes *back* in the
2585            // list as if they were less frequently used.
2586            return index;
2587        }
2588
2589        if (lrui >= mLruProcessActivityStart) {
2590            // Don't want to touch dependent processes that are hosting activities.
2591            return index;
2592        }
2593
2594        mLruProcesses.remove(lrui);
2595        if (index > 0) {
2596            index--;
2597        }
2598        if (DEBUG_LRU) Slog.d(TAG, "Moving dep from " + lrui + " to " + index
2599                + " in LRU list: " + app);
2600        mLruProcesses.add(index, app);
2601        return index;
2602    }
2603
2604    final void removeLruProcessLocked(ProcessRecord app) {
2605        int lrui = mLruProcesses.lastIndexOf(app);
2606        if (lrui >= 0) {
2607            if (lrui <= mLruProcessActivityStart) {
2608                mLruProcessActivityStart--;
2609            }
2610            if (lrui <= mLruProcessServiceStart) {
2611                mLruProcessServiceStart--;
2612            }
2613            mLruProcesses.remove(lrui);
2614        }
2615    }
2616
2617    final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
2618            ProcessRecord client) {
2619        final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
2620                || app.treatLikeActivity;
2621        final boolean hasService = false; // not impl yet. app.services.size() > 0;
2622        if (!activityChange && hasActivity) {
2623            // The process has activities, so we are only allowing activity-based adjustments
2624            // to move it.  It should be kept in the front of the list with other
2625            // processes that have activities, and we don't want those to change their
2626            // order except due to activity operations.
2627            return;
2628        }
2629
2630        mLruSeq++;
2631        final long now = SystemClock.uptimeMillis();
2632        app.lastActivityTime = now;
2633
2634        // First a quick reject: if the app is already at the position we will
2635        // put it, then there is nothing to do.
2636        if (hasActivity) {
2637            final int N = mLruProcesses.size();
2638            if (N > 0 && mLruProcesses.get(N-1) == app) {
2639                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top activity: " + app);
2640                return;
2641            }
2642        } else {
2643            if (mLruProcessServiceStart > 0
2644                    && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
2645                if (DEBUG_LRU) Slog.d(TAG, "Not moving, already top other: " + app);
2646                return;
2647            }
2648        }
2649
2650        int lrui = mLruProcesses.lastIndexOf(app);
2651
2652        if (app.persistent && lrui >= 0) {
2653            // We don't care about the position of persistent processes, as long as
2654            // they are in the list.
2655            if (DEBUG_LRU) Slog.d(TAG, "Not moving, persistent: " + app);
2656            return;
2657        }
2658
2659        /* In progress: compute new position first, so we can avoid doing work
2660           if the process is not actually going to move.  Not yet working.
2661        int addIndex;
2662        int nextIndex;
2663        boolean inActivity = false, inService = false;
2664        if (hasActivity) {
2665            // Process has activities, put it at the very tipsy-top.
2666            addIndex = mLruProcesses.size();
2667            nextIndex = mLruProcessServiceStart;
2668            inActivity = true;
2669        } else if (hasService) {
2670            // Process has services, put it at the top of the service list.
2671            addIndex = mLruProcessActivityStart;
2672            nextIndex = mLruProcessServiceStart;
2673            inActivity = true;
2674            inService = true;
2675        } else  {
2676            // Process not otherwise of interest, it goes to the top of the non-service area.
2677            addIndex = mLruProcessServiceStart;
2678            if (client != null) {
2679                int clientIndex = mLruProcesses.lastIndexOf(client);
2680                if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
2681                        + app);
2682                if (clientIndex >= 0 && addIndex > clientIndex) {
2683                    addIndex = clientIndex;
2684                }
2685            }
2686            nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
2687        }
2688
2689        Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
2690                + mLruProcessActivityStart + "): " + app);
2691        */
2692
2693        if (lrui >= 0) {
2694            if (lrui < mLruProcessActivityStart) {
2695                mLruProcessActivityStart--;
2696            }
2697            if (lrui < mLruProcessServiceStart) {
2698                mLruProcessServiceStart--;
2699            }
2700            /*
2701            if (addIndex > lrui) {
2702                addIndex--;
2703            }
2704            if (nextIndex > lrui) {
2705                nextIndex--;
2706            }
2707            */
2708            mLruProcesses.remove(lrui);
2709        }
2710
2711        /*
2712        mLruProcesses.add(addIndex, app);
2713        if (inActivity) {
2714            mLruProcessActivityStart++;
2715        }
2716        if (inService) {
2717            mLruProcessActivityStart++;
2718        }
2719        */
2720
2721        int nextIndex;
2722        if (hasActivity) {
2723            final int N = mLruProcesses.size();
2724            if (app.activities.size() == 0 && mLruProcessActivityStart < (N-1)) {
2725                // Process doesn't have activities, but has clients with
2726                // activities...  move it up, but one below the top (the top
2727                // should always have a real activity).
2728                if (DEBUG_LRU) Slog.d(TAG, "Adding to second-top of LRU activity list: " + app);
2729                mLruProcesses.add(N-1, app);
2730                // To keep it from spamming the LRU list (by making a bunch of clients),
2731                // we will push down any other entries owned by the app.
2732                final int uid = app.info.uid;
2733                for (int i=N-2; i>mLruProcessActivityStart; i--) {
2734                    ProcessRecord subProc = mLruProcesses.get(i);
2735                    if (subProc.info.uid == uid) {
2736                        // We want to push this one down the list.  If the process after
2737                        // it is for the same uid, however, don't do so, because we don't
2738                        // want them internally to be re-ordered.
2739                        if (mLruProcesses.get(i-1).info.uid != uid) {
2740                            if (DEBUG_LRU) Slog.d(TAG, "Pushing uid " + uid + " swapping at " + i
2741                                    + ": " + mLruProcesses.get(i) + " : " + mLruProcesses.get(i-1));
2742                            ProcessRecord tmp = mLruProcesses.get(i);
2743                            mLruProcesses.set(i, mLruProcesses.get(i-1));
2744                            mLruProcesses.set(i-1, tmp);
2745                            i--;
2746                        }
2747                    } else {
2748                        // A gap, we can stop here.
2749                        break;
2750                    }
2751                }
2752            } else {
2753                // Process has activities, put it at the very tipsy-top.
2754                if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU activity list: " + app);
2755                mLruProcesses.add(app);
2756            }
2757            nextIndex = mLruProcessServiceStart;
2758        } else if (hasService) {
2759            // Process has services, put it at the top of the service list.
2760            if (DEBUG_LRU) Slog.d(TAG, "Adding to top of LRU service list: " + app);
2761            mLruProcesses.add(mLruProcessActivityStart, app);
2762            nextIndex = mLruProcessServiceStart;
2763            mLruProcessActivityStart++;
2764        } else  {
2765            // Process not otherwise of interest, it goes to the top of the non-service area.
2766            int index = mLruProcessServiceStart;
2767            if (client != null) {
2768                // If there is a client, don't allow the process to be moved up higher
2769                // in the list than that client.
2770                int clientIndex = mLruProcesses.lastIndexOf(client);
2771                if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG, "Unknown client " + client
2772                        + " when updating " + app);
2773                if (clientIndex <= lrui) {
2774                    // Don't allow the client index restriction to push it down farther in the
2775                    // list than it already is.
2776                    clientIndex = lrui;
2777                }
2778                if (clientIndex >= 0 && index > clientIndex) {
2779                    index = clientIndex;
2780                }
2781            }
2782            if (DEBUG_LRU) Slog.d(TAG, "Adding at " + index + " of LRU list: " + app);
2783            mLruProcesses.add(index, app);
2784            nextIndex = index-1;
2785            mLruProcessActivityStart++;
2786            mLruProcessServiceStart++;
2787        }
2788
2789        // If the app is currently using a content provider or service,
2790        // bump those processes as well.
2791        for (int j=app.connections.size()-1; j>=0; j--) {
2792            ConnectionRecord cr = app.connections.valueAt(j);
2793            if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
2794                    && cr.binding.service.app != null
2795                    && cr.binding.service.app.lruSeq != mLruSeq
2796                    && !cr.binding.service.app.persistent) {
2797                nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
2798                        "service connection", cr, app);
2799            }
2800        }
2801        for (int j=app.conProviders.size()-1; j>=0; j--) {
2802            ContentProviderRecord cpr = app.conProviders.get(j).provider;
2803            if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
2804                nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
2805                        "provider reference", cpr, app);
2806            }
2807        }
2808    }
2809
2810    final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
2811        if (uid == Process.SYSTEM_UID) {
2812            // The system gets to run in any process.  If there are multiple
2813            // processes with the same uid, just pick the first (this
2814            // should never happen).
2815            SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
2816            if (procs == null) return null;
2817            final int N = procs.size();
2818            for (int i = 0; i < N; i++) {
2819                if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
2820            }
2821        }
2822        ProcessRecord proc = mProcessNames.get(processName, uid);
2823        if (false && proc != null && !keepIfLarge
2824                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
2825                && proc.lastCachedPss >= 4000) {
2826            // Turn this condition on to cause killing to happen regularly, for testing.
2827            if (proc.baseProcessTracker != null) {
2828                proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2829            }
2830            proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2831        } else if (proc != null && !keepIfLarge
2832                && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
2833                && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
2834            if (DEBUG_PSS) Slog.d(TAG, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
2835            if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
2836                if (proc.baseProcessTracker != null) {
2837                    proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
2838                }
2839                proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
2840            }
2841        }
2842        return proc;
2843    }
2844
2845    void ensurePackageDexOpt(String packageName) {
2846        IPackageManager pm = AppGlobals.getPackageManager();
2847        try {
2848            if (pm.performDexOptIfNeeded(packageName, null /* instruction set */)) {
2849                mDidDexOpt = true;
2850            }
2851        } catch (RemoteException e) {
2852        }
2853    }
2854
2855    boolean isNextTransitionForward() {
2856        int transit = mWindowManager.getPendingAppTransition();
2857        return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
2858                || transit == AppTransition.TRANSIT_TASK_OPEN
2859                || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
2860    }
2861
2862    int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
2863            String processName, String abiOverride, int uid, Runnable crashHandler) {
2864        synchronized(this) {
2865            ApplicationInfo info = new ApplicationInfo();
2866            // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
2867            // For isolated processes, the former contains the parent's uid and the latter the
2868            // actual uid of the isolated process.
2869            // In the special case introduced by this method (which is, starting an isolated
2870            // process directly from the SystemServer without an actual parent app process) the
2871            // closest thing to a parent's uid is SYSTEM_UID.
2872            // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
2873            // the |isolated| logic in the ProcessRecord constructor.
2874            info.uid = Process.SYSTEM_UID;
2875            info.processName = processName;
2876            info.className = entryPoint;
2877            info.packageName = "android";
2878            ProcessRecord proc = startProcessLocked(processName, info /* info */,
2879                    false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
2880                    null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
2881                    uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
2882                    crashHandler);
2883            return proc != null ? proc.pid : 0;
2884        }
2885    }
2886
2887    final ProcessRecord startProcessLocked(String processName,
2888            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
2889            String hostingType, ComponentName hostingName, boolean allowWhileBooting,
2890            boolean isolated, boolean keepIfLarge) {
2891        return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
2892                hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
2893                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
2894                null /* crashHandler */);
2895    }
2896
2897    final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
2898            boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
2899            boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
2900            String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
2901        long startTime = SystemClock.elapsedRealtime();
2902        ProcessRecord app;
2903        if (!isolated) {
2904            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2905            checkTime(startTime, "startProcess: after getProcessRecord");
2906        } else {
2907            // If this is an isolated process, it can't re-use an existing process.
2908            app = null;
2909        }
2910        // We don't have to do anything more if:
2911        // (1) There is an existing application record; and
2912        // (2) The caller doesn't think it is dead, OR there is no thread
2913        //     object attached to it so we know it couldn't have crashed; and
2914        // (3) There is a pid assigned to it, so it is either starting or
2915        //     already running.
2916        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2917                + " app=" + app + " knownToBeDead=" + knownToBeDead
2918                + " thread=" + (app != null ? app.thread : null)
2919                + " pid=" + (app != null ? app.pid : -1));
2920        if (app != null && app.pid > 0) {
2921            if (!knownToBeDead || app.thread == null) {
2922                // We already have the app running, or are waiting for it to
2923                // come up (we have a pid but not yet its thread), so keep it.
2924                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2925                // If this is a new package in the process, add the package to the list
2926                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2927                checkTime(startTime, "startProcess: done, added package to proc");
2928                return app;
2929            }
2930
2931            // An application record is attached to a previous process,
2932            // clean it up now.
2933            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2934            checkTime(startTime, "startProcess: bad proc running, killing");
2935            Process.killProcessGroup(app.info.uid, app.pid);
2936            handleAppDiedLocked(app, true, true);
2937            checkTime(startTime, "startProcess: done killing old proc");
2938        }
2939
2940        String hostingNameStr = hostingName != null
2941                ? hostingName.flattenToShortString() : null;
2942
2943        if (!isolated) {
2944            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2945                // If we are in the background, then check to see if this process
2946                // is bad.  If so, we will just silently fail.
2947                if (mBadProcesses.get(info.processName, info.uid) != null) {
2948                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2949                            + "/" + info.processName);
2950                    return null;
2951                }
2952            } else {
2953                // When the user is explicitly starting a process, then clear its
2954                // crash count so that we won't make it bad until they see at
2955                // least one crash dialog again, and make the process good again
2956                // if it had been bad.
2957                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2958                        + "/" + info.processName);
2959                mProcessCrashTimes.remove(info.processName, info.uid);
2960                if (mBadProcesses.get(info.processName, info.uid) != null) {
2961                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2962                            UserHandle.getUserId(info.uid), info.uid,
2963                            info.processName);
2964                    mBadProcesses.remove(info.processName, info.uid);
2965                    if (app != null) {
2966                        app.bad = false;
2967                    }
2968                }
2969            }
2970        }
2971
2972        if (app == null) {
2973            checkTime(startTime, "startProcess: creating new process record");
2974            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2975            app.crashHandler = crashHandler;
2976            if (app == null) {
2977                Slog.w(TAG, "Failed making new process record for "
2978                        + processName + "/" + info.uid + " isolated=" + isolated);
2979                return null;
2980            }
2981            mProcessNames.put(processName, app.uid, app);
2982            if (isolated) {
2983                mIsolatedProcesses.put(app.uid, app);
2984            }
2985            checkTime(startTime, "startProcess: done creating new process record");
2986        } else {
2987            // If this is a new package in the process, add the package to the list
2988            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2989            checkTime(startTime, "startProcess: added package to existing proc");
2990        }
2991
2992        // If the system is not ready yet, then hold off on starting this
2993        // process until it is.
2994        if (!mProcessesReady
2995                && !isAllowedWhileBooting(info)
2996                && !allowWhileBooting) {
2997            if (!mProcessesOnHold.contains(app)) {
2998                mProcessesOnHold.add(app);
2999            }
3000            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
3001            return app;
3002        }
3003
3004        startProcessLocked(
3005                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3006        checkTime(startTime, "startProcess: done starting proc!");
3007        return (app.pid != 0) ? app : null;
3008    }
3009
3010    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3011        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3012    }
3013
3014    private final void startProcessLocked(ProcessRecord app,
3015            String hostingType, String hostingNameStr) {
3016        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3017                null /* entryPoint */, null /* entryPointArgs */);
3018    }
3019
3020    private final void startProcessLocked(ProcessRecord app, String hostingType,
3021            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3022        long startTime = SystemClock.elapsedRealtime();
3023        if (app.pid > 0 && app.pid != MY_PID) {
3024            checkTime(startTime, "startProcess: removing from pids map");
3025            synchronized (mPidsSelfLocked) {
3026                mPidsSelfLocked.remove(app.pid);
3027                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3028            }
3029            checkTime(startTime, "startProcess: done removing from pids map");
3030            app.setPid(0);
3031        }
3032
3033        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3034                "startProcessLocked removing on hold: " + app);
3035        mProcessesOnHold.remove(app);
3036
3037        checkTime(startTime, "startProcess: starting to update cpu stats");
3038        updateCpuStats();
3039        checkTime(startTime, "startProcess: done updating cpu stats");
3040
3041        try {
3042            int uid = app.uid;
3043
3044            int[] gids = null;
3045            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3046            if (!app.isolated) {
3047                int[] permGids = null;
3048                try {
3049                    checkTime(startTime, "startProcess: getting gids from package manager");
3050                    final PackageManager pm = mContext.getPackageManager();
3051                    permGids = pm.getPackageGids(app.info.packageName);
3052
3053                    if (Environment.isExternalStorageEmulated()) {
3054                        checkTime(startTime, "startProcess: checking external storage perm");
3055                        if (pm.checkPermission(
3056                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3057                                app.info.packageName) == PERMISSION_GRANTED) {
3058                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3059                        } else {
3060                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3061                        }
3062                    }
3063                } catch (PackageManager.NameNotFoundException e) {
3064                    Slog.w(TAG, "Unable to retrieve gids", e);
3065                }
3066
3067                /*
3068                 * Add shared application and profile GIDs so applications can share some
3069                 * resources like shared libraries and access user-wide resources
3070                 */
3071                if (permGids == null) {
3072                    gids = new int[2];
3073                } else {
3074                    gids = new int[permGids.length + 2];
3075                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3076                }
3077                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3078                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3079            }
3080            checkTime(startTime, "startProcess: building args");
3081            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3082                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3083                        && mTopComponent != null
3084                        && app.processName.equals(mTopComponent.getPackageName())) {
3085                    uid = 0;
3086                }
3087                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3088                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3089                    uid = 0;
3090                }
3091            }
3092            int debugFlags = 0;
3093            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3094                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3095                // Also turn on CheckJNI for debuggable apps. It's quite
3096                // awkward to turn on otherwise.
3097                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3098            }
3099            // Run the app in safe mode if its manifest requests so or the
3100            // system is booted in safe mode.
3101            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3102                mSafeMode == true) {
3103                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3104            }
3105            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3106                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3107            }
3108            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3109                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3110            }
3111            if ("1".equals(SystemProperties.get("debug.assert"))) {
3112                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3113            }
3114
3115            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3116            if (requiredAbi == null) {
3117                requiredAbi = Build.SUPPORTED_ABIS[0];
3118            }
3119
3120            // Start the process.  It will either succeed and return a result containing
3121            // the PID of the new process, or else throw a RuntimeException.
3122            boolean isActivityProcess = (entryPoint == null);
3123            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3124            checkTime(startTime, "startProcess: asking zygote to start proc");
3125            Process.ProcessStartResult startResult = Process.start(entryPoint,
3126                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3127                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3128            checkTime(startTime, "startProcess: returned from zygote!");
3129
3130            checkTime(startTime, "startProcess: noting battery stats update");
3131            if (app.isolated) {
3132                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3133            }
3134            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3135            checkTime(startTime, "startProcess: done updating battery stats");
3136
3137            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3138                    UserHandle.getUserId(uid), startResult.pid, uid,
3139                    app.processName, hostingType,
3140                    hostingNameStr != null ? hostingNameStr : "");
3141
3142            if (app.persistent) {
3143                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3144            }
3145
3146            checkTime(startTime, "startProcess: building log message");
3147            StringBuilder buf = mStringBuilder;
3148            buf.setLength(0);
3149            buf.append("Start proc ");
3150            buf.append(app.processName);
3151            if (!isActivityProcess) {
3152                buf.append(" [");
3153                buf.append(entryPoint);
3154                buf.append("]");
3155            }
3156            buf.append(" for ");
3157            buf.append(hostingType);
3158            if (hostingNameStr != null) {
3159                buf.append(" ");
3160                buf.append(hostingNameStr);
3161            }
3162            buf.append(": pid=");
3163            buf.append(startResult.pid);
3164            buf.append(" uid=");
3165            buf.append(uid);
3166            buf.append(" gids={");
3167            if (gids != null) {
3168                for (int gi=0; gi<gids.length; gi++) {
3169                    if (gi != 0) buf.append(", ");
3170                    buf.append(gids[gi]);
3171
3172                }
3173            }
3174            buf.append("}");
3175            if (requiredAbi != null) {
3176                buf.append(" abi=");
3177                buf.append(requiredAbi);
3178            }
3179            Slog.i(TAG, buf.toString());
3180            app.setPid(startResult.pid);
3181            app.usingWrapper = startResult.usingWrapper;
3182            app.removed = false;
3183            app.killedByAm = false;
3184            checkTime(startTime, "startProcess: starting to update pids map");
3185            synchronized (mPidsSelfLocked) {
3186                this.mPidsSelfLocked.put(startResult.pid, app);
3187                if (isActivityProcess) {
3188                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3189                    msg.obj = app;
3190                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3191                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3192                }
3193            }
3194            checkTime(startTime, "startProcess: done updating pids map");
3195        } catch (RuntimeException e) {
3196            // XXX do better error recovery.
3197            app.setPid(0);
3198            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3199            if (app.isolated) {
3200                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3201            }
3202            Slog.e(TAG, "Failure starting process " + app.processName, e);
3203        }
3204    }
3205
3206    void updateUsageStats(ActivityRecord component, boolean resumed) {
3207        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3208        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3209        if (resumed) {
3210            if (mUsageStatsService != null) {
3211                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3212                        System.currentTimeMillis(),
3213                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3214            }
3215            synchronized (stats) {
3216                stats.noteActivityResumedLocked(component.app.uid);
3217            }
3218        } else {
3219            if (mUsageStatsService != null) {
3220                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3221                        System.currentTimeMillis(),
3222                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3223            }
3224            synchronized (stats) {
3225                stats.noteActivityPausedLocked(component.app.uid);
3226            }
3227        }
3228    }
3229
3230    Intent getHomeIntent() {
3231        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3232        intent.setComponent(mTopComponent);
3233        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3234            intent.addCategory(Intent.CATEGORY_HOME);
3235        }
3236        return intent;
3237    }
3238
3239    boolean startHomeActivityLocked(int userId) {
3240        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3241                && mTopAction == null) {
3242            // We are running in factory test mode, but unable to find
3243            // the factory test app, so just sit around displaying the
3244            // error message and don't try to start anything.
3245            return false;
3246        }
3247        Intent intent = getHomeIntent();
3248        ActivityInfo aInfo =
3249            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3250        if (aInfo != null) {
3251            intent.setComponent(new ComponentName(
3252                    aInfo.applicationInfo.packageName, aInfo.name));
3253            // Don't do this if the home app is currently being
3254            // instrumented.
3255            aInfo = new ActivityInfo(aInfo);
3256            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3257            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3258                    aInfo.applicationInfo.uid, true);
3259            if (app == null || app.instrumentationClass == null) {
3260                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3261                mStackSupervisor.startHomeActivity(intent, aInfo);
3262            }
3263        }
3264
3265        return true;
3266    }
3267
3268    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3269        ActivityInfo ai = null;
3270        ComponentName comp = intent.getComponent();
3271        try {
3272            if (comp != null) {
3273                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3274            } else {
3275                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3276                        intent,
3277                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3278                            flags, userId);
3279
3280                if (info != null) {
3281                    ai = info.activityInfo;
3282                }
3283            }
3284        } catch (RemoteException e) {
3285            // ignore
3286        }
3287
3288        return ai;
3289    }
3290
3291    /**
3292     * Starts the "new version setup screen" if appropriate.
3293     */
3294    void startSetupActivityLocked() {
3295        // Only do this once per boot.
3296        if (mCheckedForSetup) {
3297            return;
3298        }
3299
3300        // We will show this screen if the current one is a different
3301        // version than the last one shown, and we are not running in
3302        // low-level factory test mode.
3303        final ContentResolver resolver = mContext.getContentResolver();
3304        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3305                Settings.Global.getInt(resolver,
3306                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3307            mCheckedForSetup = true;
3308
3309            // See if we should be showing the platform update setup UI.
3310            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3311            List<ResolveInfo> ris = mContext.getPackageManager()
3312                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3313
3314            // We don't allow third party apps to replace this.
3315            ResolveInfo ri = null;
3316            for (int i=0; ris != null && i<ris.size(); i++) {
3317                if ((ris.get(i).activityInfo.applicationInfo.flags
3318                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3319                    ri = ris.get(i);
3320                    break;
3321                }
3322            }
3323
3324            if (ri != null) {
3325                String vers = ri.activityInfo.metaData != null
3326                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3327                        : null;
3328                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3329                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3330                            Intent.METADATA_SETUP_VERSION);
3331                }
3332                String lastVers = Settings.Secure.getString(
3333                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3334                if (vers != null && !vers.equals(lastVers)) {
3335                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3336                    intent.setComponent(new ComponentName(
3337                            ri.activityInfo.packageName, ri.activityInfo.name));
3338                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3339                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3340                            null);
3341                }
3342            }
3343        }
3344    }
3345
3346    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3347        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3348    }
3349
3350    void enforceNotIsolatedCaller(String caller) {
3351        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3352            throw new SecurityException("Isolated process not allowed to call " + caller);
3353        }
3354    }
3355
3356    @Override
3357    public int getFrontActivityScreenCompatMode() {
3358        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3359        synchronized (this) {
3360            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3361        }
3362    }
3363
3364    @Override
3365    public void setFrontActivityScreenCompatMode(int mode) {
3366        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3367                "setFrontActivityScreenCompatMode");
3368        synchronized (this) {
3369            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3370        }
3371    }
3372
3373    @Override
3374    public int getPackageScreenCompatMode(String packageName) {
3375        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3376        synchronized (this) {
3377            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3378        }
3379    }
3380
3381    @Override
3382    public void setPackageScreenCompatMode(String packageName, int mode) {
3383        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3384                "setPackageScreenCompatMode");
3385        synchronized (this) {
3386            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3387        }
3388    }
3389
3390    @Override
3391    public boolean getPackageAskScreenCompat(String packageName) {
3392        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3393        synchronized (this) {
3394            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3395        }
3396    }
3397
3398    @Override
3399    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3400        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3401                "setPackageAskScreenCompat");
3402        synchronized (this) {
3403            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3404        }
3405    }
3406
3407    private void dispatchProcessesChanged() {
3408        int N;
3409        synchronized (this) {
3410            N = mPendingProcessChanges.size();
3411            if (mActiveProcessChanges.length < N) {
3412                mActiveProcessChanges = new ProcessChangeItem[N];
3413            }
3414            mPendingProcessChanges.toArray(mActiveProcessChanges);
3415            mAvailProcessChanges.addAll(mPendingProcessChanges);
3416            mPendingProcessChanges.clear();
3417            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3418        }
3419
3420        int i = mProcessObservers.beginBroadcast();
3421        while (i > 0) {
3422            i--;
3423            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3424            if (observer != null) {
3425                try {
3426                    for (int j=0; j<N; j++) {
3427                        ProcessChangeItem item = mActiveProcessChanges[j];
3428                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3429                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3430                                    + item.pid + " uid=" + item.uid + ": "
3431                                    + item.foregroundActivities);
3432                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3433                                    item.foregroundActivities);
3434                        }
3435                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3436                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3437                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3438                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3439                        }
3440                    }
3441                } catch (RemoteException e) {
3442                }
3443            }
3444        }
3445        mProcessObservers.finishBroadcast();
3446    }
3447
3448    private void dispatchProcessDied(int pid, int uid) {
3449        int i = mProcessObservers.beginBroadcast();
3450        while (i > 0) {
3451            i--;
3452            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3453            if (observer != null) {
3454                try {
3455                    observer.onProcessDied(pid, uid);
3456                } catch (RemoteException e) {
3457                }
3458            }
3459        }
3460        mProcessObservers.finishBroadcast();
3461    }
3462
3463    @Override
3464    public final int startActivity(IApplicationThread caller, String callingPackage,
3465            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3466            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3467        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3468            resultWho, requestCode, startFlags, profilerInfo, options,
3469            UserHandle.getCallingUserId());
3470    }
3471
3472    @Override
3473    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3474            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3475            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3476        enforceNotIsolatedCaller("startActivity");
3477        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3478                false, ALLOW_FULL_ONLY, "startActivity", null);
3479        // TODO: Switch to user app stacks here.
3480        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3481                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3482                profilerInfo, null, null, options, userId, null, null);
3483    }
3484
3485    @Override
3486    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3487            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3488            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3489
3490        // This is very dangerous -- it allows you to perform a start activity (including
3491        // permission grants) as any app that may launch one of your own activities.  So
3492        // we will only allow this to be done from activities that are part of the core framework,
3493        // and then only when they are running as the system.
3494        final ActivityRecord sourceRecord;
3495        final int targetUid;
3496        final String targetPackage;
3497        synchronized (this) {
3498            if (resultTo == null) {
3499                throw new SecurityException("Must be called from an activity");
3500            }
3501            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3502            if (sourceRecord == null) {
3503                throw new SecurityException("Called with bad activity token: " + resultTo);
3504            }
3505            if (!sourceRecord.info.packageName.equals("android")) {
3506                throw new SecurityException(
3507                        "Must be called from an activity that is declared in the android package");
3508            }
3509            if (sourceRecord.app == null) {
3510                throw new SecurityException("Called without a process attached to activity");
3511            }
3512            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3513                // This is still okay, as long as this activity is running under the
3514                // uid of the original calling activity.
3515                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3516                    throw new SecurityException(
3517                            "Calling activity in uid " + sourceRecord.app.uid
3518                                    + " must be system uid or original calling uid "
3519                                    + sourceRecord.launchedFromUid);
3520                }
3521            }
3522            targetUid = sourceRecord.launchedFromUid;
3523            targetPackage = sourceRecord.launchedFromPackage;
3524        }
3525
3526        // TODO: Switch to user app stacks here.
3527        try {
3528            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3529                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3530                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3531            return ret;
3532        } catch (SecurityException e) {
3533            // XXX need to figure out how to propagate to original app.
3534            // A SecurityException here is generally actually a fault of the original
3535            // calling activity (such as a fairly granting permissions), so propagate it
3536            // back to them.
3537            /*
3538            StringBuilder msg = new StringBuilder();
3539            msg.append("While launching");
3540            msg.append(intent.toString());
3541            msg.append(": ");
3542            msg.append(e.getMessage());
3543            */
3544            throw e;
3545        }
3546    }
3547
3548    @Override
3549    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3550            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3551            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3552        enforceNotIsolatedCaller("startActivityAndWait");
3553        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3554                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3555        WaitResult res = new WaitResult();
3556        // TODO: Switch to user app stacks here.
3557        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3558                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3559                options, userId, null, null);
3560        return res;
3561    }
3562
3563    @Override
3564    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3565            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3566            int startFlags, Configuration config, Bundle options, int userId) {
3567        enforceNotIsolatedCaller("startActivityWithConfig");
3568        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3569                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3570        // TODO: Switch to user app stacks here.
3571        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3572                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3573                null, null, config, options, userId, null, null);
3574        return ret;
3575    }
3576
3577    @Override
3578    public int startActivityIntentSender(IApplicationThread caller,
3579            IntentSender intent, Intent fillInIntent, String resolvedType,
3580            IBinder resultTo, String resultWho, int requestCode,
3581            int flagsMask, int flagsValues, Bundle options) {
3582        enforceNotIsolatedCaller("startActivityIntentSender");
3583        // Refuse possible leaked file descriptors
3584        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3585            throw new IllegalArgumentException("File descriptors passed in Intent");
3586        }
3587
3588        IIntentSender sender = intent.getTarget();
3589        if (!(sender instanceof PendingIntentRecord)) {
3590            throw new IllegalArgumentException("Bad PendingIntent object");
3591        }
3592
3593        PendingIntentRecord pir = (PendingIntentRecord)sender;
3594
3595        synchronized (this) {
3596            // If this is coming from the currently resumed activity, it is
3597            // effectively saying that app switches are allowed at this point.
3598            final ActivityStack stack = getFocusedStack();
3599            if (stack.mResumedActivity != null &&
3600                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3601                mAppSwitchesAllowedTime = 0;
3602            }
3603        }
3604        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3605                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3606        return ret;
3607    }
3608
3609    @Override
3610    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3611            Intent intent, String resolvedType, IVoiceInteractionSession session,
3612            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3613            Bundle options, int userId) {
3614        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3615                != PackageManager.PERMISSION_GRANTED) {
3616            String msg = "Permission Denial: startVoiceActivity() from pid="
3617                    + Binder.getCallingPid()
3618                    + ", uid=" + Binder.getCallingUid()
3619                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3620            Slog.w(TAG, msg);
3621            throw new SecurityException(msg);
3622        }
3623        if (session == null || interactor == null) {
3624            throw new NullPointerException("null session or interactor");
3625        }
3626        userId = handleIncomingUser(callingPid, callingUid, userId,
3627                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3628        // TODO: Switch to user app stacks here.
3629        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3630                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3631                null, options, userId, null, null);
3632    }
3633
3634    @Override
3635    public boolean startNextMatchingActivity(IBinder callingActivity,
3636            Intent intent, Bundle options) {
3637        // Refuse possible leaked file descriptors
3638        if (intent != null && intent.hasFileDescriptors() == true) {
3639            throw new IllegalArgumentException("File descriptors passed in Intent");
3640        }
3641
3642        synchronized (this) {
3643            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3644            if (r == null) {
3645                ActivityOptions.abort(options);
3646                return false;
3647            }
3648            if (r.app == null || r.app.thread == null) {
3649                // The caller is not running...  d'oh!
3650                ActivityOptions.abort(options);
3651                return false;
3652            }
3653            intent = new Intent(intent);
3654            // The caller is not allowed to change the data.
3655            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3656            // And we are resetting to find the next component...
3657            intent.setComponent(null);
3658
3659            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3660
3661            ActivityInfo aInfo = null;
3662            try {
3663                List<ResolveInfo> resolves =
3664                    AppGlobals.getPackageManager().queryIntentActivities(
3665                            intent, r.resolvedType,
3666                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3667                            UserHandle.getCallingUserId());
3668
3669                // Look for the original activity in the list...
3670                final int N = resolves != null ? resolves.size() : 0;
3671                for (int i=0; i<N; i++) {
3672                    ResolveInfo rInfo = resolves.get(i);
3673                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3674                            && rInfo.activityInfo.name.equals(r.info.name)) {
3675                        // We found the current one...  the next matching is
3676                        // after it.
3677                        i++;
3678                        if (i<N) {
3679                            aInfo = resolves.get(i).activityInfo;
3680                        }
3681                        if (debug) {
3682                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3683                                    + "/" + r.info.name);
3684                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3685                                    + "/" + aInfo.name);
3686                        }
3687                        break;
3688                    }
3689                }
3690            } catch (RemoteException e) {
3691            }
3692
3693            if (aInfo == null) {
3694                // Nobody who is next!
3695                ActivityOptions.abort(options);
3696                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3697                return false;
3698            }
3699
3700            intent.setComponent(new ComponentName(
3701                    aInfo.applicationInfo.packageName, aInfo.name));
3702            intent.setFlags(intent.getFlags()&~(
3703                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3704                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3705                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3706                    Intent.FLAG_ACTIVITY_NEW_TASK));
3707
3708            // Okay now we need to start the new activity, replacing the
3709            // currently running activity.  This is a little tricky because
3710            // we want to start the new one as if the current one is finished,
3711            // but not finish the current one first so that there is no flicker.
3712            // And thus...
3713            final boolean wasFinishing = r.finishing;
3714            r.finishing = true;
3715
3716            // Propagate reply information over to the new activity.
3717            final ActivityRecord resultTo = r.resultTo;
3718            final String resultWho = r.resultWho;
3719            final int requestCode = r.requestCode;
3720            r.resultTo = null;
3721            if (resultTo != null) {
3722                resultTo.removeResultsLocked(r, resultWho, requestCode);
3723            }
3724
3725            final long origId = Binder.clearCallingIdentity();
3726            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3727                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3728                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3729                    options, false, null, null, null);
3730            Binder.restoreCallingIdentity(origId);
3731
3732            r.finishing = wasFinishing;
3733            if (res != ActivityManager.START_SUCCESS) {
3734                return false;
3735            }
3736            return true;
3737        }
3738    }
3739
3740    @Override
3741    public final int startActivityFromRecents(int taskId, Bundle options) {
3742        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3743            String msg = "Permission Denial: startActivityFromRecents called without " +
3744                    START_TASKS_FROM_RECENTS;
3745            Slog.w(TAG, msg);
3746            throw new SecurityException(msg);
3747        }
3748        return startActivityFromRecentsInner(taskId, options);
3749    }
3750
3751    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3752        final TaskRecord task;
3753        final int callingUid;
3754        final String callingPackage;
3755        final Intent intent;
3756        final int userId;
3757        synchronized (this) {
3758            task = recentTaskForIdLocked(taskId);
3759            if (task == null) {
3760                throw new IllegalArgumentException("Task " + taskId + " not found.");
3761            }
3762            callingUid = task.mCallingUid;
3763            callingPackage = task.mCallingPackage;
3764            intent = task.intent;
3765            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3766            userId = task.userId;
3767        }
3768        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3769                options, userId, null, task);
3770    }
3771
3772    final int startActivityInPackage(int uid, String callingPackage,
3773            Intent intent, String resolvedType, IBinder resultTo,
3774            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3775            IActivityContainer container, TaskRecord inTask) {
3776
3777        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3778                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3779
3780        // TODO: Switch to user app stacks here.
3781        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3782                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3783                null, null, null, options, userId, container, inTask);
3784        return ret;
3785    }
3786
3787    @Override
3788    public final int startActivities(IApplicationThread caller, String callingPackage,
3789            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3790            int userId) {
3791        enforceNotIsolatedCaller("startActivities");
3792        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3793                false, ALLOW_FULL_ONLY, "startActivity", null);
3794        // TODO: Switch to user app stacks here.
3795        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3796                resolvedTypes, resultTo, options, userId);
3797        return ret;
3798    }
3799
3800    final int startActivitiesInPackage(int uid, String callingPackage,
3801            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3802            Bundle options, int userId) {
3803
3804        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3805                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3806        // TODO: Switch to user app stacks here.
3807        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3808                resultTo, options, userId);
3809        return ret;
3810    }
3811
3812    //explicitly remove thd old information in mRecentTasks when removing existing user.
3813    private void removeRecentTasksForUserLocked(int userId) {
3814        if(userId <= 0) {
3815            Slog.i(TAG, "Can't remove recent task on user " + userId);
3816            return;
3817        }
3818
3819        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3820            TaskRecord tr = mRecentTasks.get(i);
3821            if (tr.userId == userId) {
3822                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3823                        + " when finishing user" + userId);
3824                mRecentTasks.remove(i);
3825                tr.removedFromRecents(mTaskPersister);
3826            }
3827        }
3828
3829        // Remove tasks from persistent storage.
3830        mTaskPersister.wakeup(null, true);
3831    }
3832
3833    /**
3834     * Update the recent tasks lists: make sure tasks should still be here (their
3835     * applications / activities still exist), update their availability, fixup ordering
3836     * of affiliations.
3837     */
3838    void cleanupRecentTasksLocked(int userId) {
3839        if (mRecentTasks == null) {
3840            // Happens when called from the packagemanager broadcast before boot.
3841            return;
3842        }
3843
3844        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3845        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3846        final IPackageManager pm = AppGlobals.getPackageManager();
3847        final ActivityInfo dummyAct = new ActivityInfo();
3848        final ApplicationInfo dummyApp = new ApplicationInfo();
3849
3850        int N = mRecentTasks.size();
3851
3852        int[] users = userId == UserHandle.USER_ALL
3853                ? getUsersLocked() : new int[] { userId };
3854        for (int user : users) {
3855            for (int i = 0; i < N; i++) {
3856                TaskRecord task = mRecentTasks.get(i);
3857                if (task.userId != user) {
3858                    // Only look at tasks for the user ID of interest.
3859                    continue;
3860                }
3861                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3862                    // This situation is broken, and we should just get rid of it now.
3863                    mRecentTasks.remove(i);
3864                    task.removedFromRecents(mTaskPersister);
3865                    i--;
3866                    N--;
3867                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3868                    continue;
3869                }
3870                // Check whether this activity is currently available.
3871                if (task.realActivity != null) {
3872                    ActivityInfo ai = availActCache.get(task.realActivity);
3873                    if (ai == null) {
3874                        try {
3875                            ai = pm.getActivityInfo(task.realActivity,
3876                                    PackageManager.GET_UNINSTALLED_PACKAGES
3877                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3878                        } catch (RemoteException e) {
3879                            // Will never happen.
3880                            continue;
3881                        }
3882                        if (ai == null) {
3883                            ai = dummyAct;
3884                        }
3885                        availActCache.put(task.realActivity, ai);
3886                    }
3887                    if (ai == dummyAct) {
3888                        // This could be either because the activity no longer exists, or the
3889                        // app is temporarily gone.  For the former we want to remove the recents
3890                        // entry; for the latter we want to mark it as unavailable.
3891                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3892                        if (app == null) {
3893                            try {
3894                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3895                                        PackageManager.GET_UNINSTALLED_PACKAGES
3896                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3897                            } catch (RemoteException e) {
3898                                // Will never happen.
3899                                continue;
3900                            }
3901                            if (app == null) {
3902                                app = dummyApp;
3903                            }
3904                            availAppCache.put(task.realActivity.getPackageName(), app);
3905                        }
3906                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3907                            // Doesn't exist any more!  Good-bye.
3908                            mRecentTasks.remove(i);
3909                            task.removedFromRecents(mTaskPersister);
3910                            i--;
3911                            N--;
3912                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3913                            continue;
3914                        } else {
3915                            // Otherwise just not available for now.
3916                            if (task.isAvailable) {
3917                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3918                                        + task);
3919                            }
3920                            task.isAvailable = false;
3921                        }
3922                    } else {
3923                        if (!ai.enabled || !ai.applicationInfo.enabled
3924                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3925                            if (task.isAvailable) {
3926                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3927                                        + task + " (enabled=" + ai.enabled + "/"
3928                                        + ai.applicationInfo.enabled +  " flags="
3929                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3930                            }
3931                            task.isAvailable = false;
3932                        } else {
3933                            if (!task.isAvailable) {
3934                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3935                                        + task);
3936                            }
3937                            task.isAvailable = true;
3938                        }
3939                    }
3940                }
3941            }
3942        }
3943
3944        // Verify the affiliate chain for each task.
3945        for (int i = 0; i < N; ) {
3946            TaskRecord task = mRecentTasks.remove(i);
3947            if (mTmpRecents.contains(task)) {
3948                continue;
3949            }
3950            int affiliatedTaskId = task.mAffiliatedTaskId;
3951            while (true) {
3952                TaskRecord next = task.mNextAffiliate;
3953                if (next == null) {
3954                    break;
3955                }
3956                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3957                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3958                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3959                    task.setNextAffiliate(null);
3960                    if (next.mPrevAffiliate == task) {
3961                        next.setPrevAffiliate(null);
3962                    }
3963                    break;
3964                }
3965                if (next.mPrevAffiliate != task) {
3966                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3967                            next.mPrevAffiliate + " task=" + task);
3968                    next.setPrevAffiliate(null);
3969                    task.setNextAffiliate(null);
3970                    break;
3971                }
3972                if (!mRecentTasks.contains(next)) {
3973                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3974                    task.setNextAffiliate(null);
3975                    // We know that next.mPrevAffiliate is always task, from above, so clear
3976                    // its previous affiliate.
3977                    next.setPrevAffiliate(null);
3978                    break;
3979                }
3980                task = next;
3981            }
3982            // task is now the end of the list
3983            do {
3984                mRecentTasks.remove(task);
3985                mRecentTasks.add(i++, task);
3986                mTmpRecents.add(task);
3987                task.inRecents = true;
3988            } while ((task = task.mPrevAffiliate) != null);
3989        }
3990        mTmpRecents.clear();
3991        // mRecentTasks is now in sorted, affiliated order.
3992    }
3993
3994    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3995        int N = mRecentTasks.size();
3996        TaskRecord top = task;
3997        int topIndex = taskIndex;
3998        while (top.mNextAffiliate != null && topIndex > 0) {
3999            top = top.mNextAffiliate;
4000            topIndex--;
4001        }
4002        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
4003                + topIndex + " from intial " + taskIndex);
4004        // Find the end of the chain, doing a sanity check along the way.
4005        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
4006        int endIndex = topIndex;
4007        TaskRecord prev = top;
4008        while (endIndex < N) {
4009            TaskRecord cur = mRecentTasks.get(endIndex);
4010            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
4011                    + endIndex + " " + cur);
4012            if (cur == top) {
4013                // Verify start of the chain.
4014                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
4015                    Slog.wtf(TAG, "Bad chain @" + endIndex
4016                            + ": first task has next affiliate: " + prev);
4017                    sane = false;
4018                    break;
4019                }
4020            } else {
4021                // Verify middle of the chain's next points back to the one before.
4022                if (cur.mNextAffiliate != prev
4023                        || cur.mNextAffiliateTaskId != prev.taskId) {
4024                    Slog.wtf(TAG, "Bad chain @" + endIndex
4025                            + ": middle task " + cur + " @" + endIndex
4026                            + " has bad next affiliate "
4027                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4028                            + ", expected " + prev);
4029                    sane = false;
4030                    break;
4031                }
4032            }
4033            if (cur.mPrevAffiliateTaskId == -1) {
4034                // Chain ends here.
4035                if (cur.mPrevAffiliate != null) {
4036                    Slog.wtf(TAG, "Bad chain @" + endIndex
4037                            + ": last task " + cur + " has previous affiliate "
4038                            + cur.mPrevAffiliate);
4039                    sane = false;
4040                }
4041                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4042                break;
4043            } else {
4044                // Verify middle of the chain's prev points to a valid item.
4045                if (cur.mPrevAffiliate == null) {
4046                    Slog.wtf(TAG, "Bad chain @" + endIndex
4047                            + ": task " + cur + " has previous affiliate "
4048                            + cur.mPrevAffiliate + " but should be id "
4049                            + cur.mPrevAffiliate);
4050                    sane = false;
4051                    break;
4052                }
4053            }
4054            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4055                Slog.wtf(TAG, "Bad chain @" + endIndex
4056                        + ": task " + cur + " has affiliated id "
4057                        + cur.mAffiliatedTaskId + " but should be "
4058                        + task.mAffiliatedTaskId);
4059                sane = false;
4060                break;
4061            }
4062            prev = cur;
4063            endIndex++;
4064            if (endIndex >= N) {
4065                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4066                        + ": last task " + prev);
4067                sane = false;
4068                break;
4069            }
4070        }
4071        if (sane) {
4072            if (endIndex < taskIndex) {
4073                Slog.wtf(TAG, "Bad chain @" + endIndex
4074                        + ": did not extend to task " + task + " @" + taskIndex);
4075                sane = false;
4076            }
4077        }
4078        if (sane) {
4079            // All looks good, we can just move all of the affiliated tasks
4080            // to the top.
4081            for (int i=topIndex; i<=endIndex; i++) {
4082                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4083                        + " from " + i + " to " + (i-topIndex));
4084                TaskRecord cur = mRecentTasks.remove(i);
4085                mRecentTasks.add(i-topIndex, cur);
4086            }
4087            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4088                    + " to " + endIndex);
4089            return true;
4090        }
4091
4092        // Whoops, couldn't do it.
4093        return false;
4094    }
4095
4096    final void addRecentTaskLocked(TaskRecord task) {
4097        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4098                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4099
4100        int N = mRecentTasks.size();
4101        // Quick case: check if the top-most recent task is the same.
4102        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4103            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4104            return;
4105        }
4106        // Another quick case: check if this is part of a set of affiliated
4107        // tasks that are at the top.
4108        if (isAffiliated && N > 0 && task.inRecents
4109                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4110            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4111                    + " at top when adding " + task);
4112            return;
4113        }
4114        // Another quick case: never add voice sessions.
4115        if (task.voiceSession != null) {
4116            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4117            return;
4118        }
4119
4120        boolean needAffiliationFix = false;
4121
4122        // Slightly less quick case: the task is already in recents, so all we need
4123        // to do is move it.
4124        if (task.inRecents) {
4125            int taskIndex = mRecentTasks.indexOf(task);
4126            if (taskIndex >= 0) {
4127                if (!isAffiliated) {
4128                    // Simple case: this is not an affiliated task, so we just move it to the front.
4129                    mRecentTasks.remove(taskIndex);
4130                    mRecentTasks.add(0, task);
4131                    notifyTaskPersisterLocked(task, false);
4132                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4133                            + " from " + taskIndex);
4134                    return;
4135                } else {
4136                    // More complicated: need to keep all affiliated tasks together.
4137                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4138                        // All went well.
4139                        return;
4140                    }
4141
4142                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4143                    // everything and then go through our general path of adding a new task.
4144                    needAffiliationFix = true;
4145                }
4146            } else {
4147                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4148                needAffiliationFix = true;
4149            }
4150        }
4151
4152        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4153        trimRecentsForTask(task, true);
4154
4155        N = mRecentTasks.size();
4156        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4157            final TaskRecord tr = mRecentTasks.remove(N - 1);
4158            tr.removedFromRecents(mTaskPersister);
4159            N--;
4160        }
4161        task.inRecents = true;
4162        if (!isAffiliated || needAffiliationFix) {
4163            // If this is a simple non-affiliated task, or we had some failure trying to
4164            // handle it as part of an affilated task, then just place it at the top.
4165            mRecentTasks.add(0, task);
4166        } else if (isAffiliated) {
4167            // If this is a new affiliated task, then move all of the affiliated tasks
4168            // to the front and insert this new one.
4169            TaskRecord other = task.mNextAffiliate;
4170            if (other == null) {
4171                other = task.mPrevAffiliate;
4172            }
4173            if (other != null) {
4174                int otherIndex = mRecentTasks.indexOf(other);
4175                if (otherIndex >= 0) {
4176                    // Insert new task at appropriate location.
4177                    int taskIndex;
4178                    if (other == task.mNextAffiliate) {
4179                        // We found the index of our next affiliation, which is who is
4180                        // before us in the list, so add after that point.
4181                        taskIndex = otherIndex+1;
4182                    } else {
4183                        // We found the index of our previous affiliation, which is who is
4184                        // after us in the list, so add at their position.
4185                        taskIndex = otherIndex;
4186                    }
4187                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4188                            + taskIndex + ": " + task);
4189                    mRecentTasks.add(taskIndex, task);
4190
4191                    // Now move everything to the front.
4192                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4193                        // All went well.
4194                        return;
4195                    }
4196
4197                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4198                    // everything and then go through our general path of adding a new task.
4199                    needAffiliationFix = true;
4200                } else {
4201                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4202                            + other);
4203                    needAffiliationFix = true;
4204                }
4205            } else {
4206                if (DEBUG_RECENTS) Slog.d(TAG,
4207                        "addRecent: adding affiliated task without next/prev:" + task);
4208                needAffiliationFix = true;
4209            }
4210        }
4211        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4212
4213        if (needAffiliationFix) {
4214            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4215            cleanupRecentTasksLocked(task.userId);
4216        }
4217    }
4218
4219    /**
4220     * If needed, remove oldest existing entries in recents that are for the same kind
4221     * of task as the given one.
4222     */
4223    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4224        int N = mRecentTasks.size();
4225        final Intent intent = task.intent;
4226        final boolean document = intent != null && intent.isDocument();
4227
4228        int maxRecents = task.maxRecents - 1;
4229        for (int i=0; i<N; i++) {
4230            final TaskRecord tr = mRecentTasks.get(i);
4231            if (task != tr) {
4232                if (task.userId != tr.userId) {
4233                    continue;
4234                }
4235                if (i > MAX_RECENT_BITMAPS) {
4236                    tr.freeLastThumbnail();
4237                }
4238                final Intent trIntent = tr.intent;
4239                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4240                    (intent == null || !intent.filterEquals(trIntent))) {
4241                    continue;
4242                }
4243                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4244                if (document && trIsDocument) {
4245                    // These are the same document activity (not necessarily the same doc).
4246                    if (maxRecents > 0) {
4247                        --maxRecents;
4248                        continue;
4249                    }
4250                    // Hit the maximum number of documents for this task. Fall through
4251                    // and remove this document from recents.
4252                } else if (document || trIsDocument) {
4253                    // Only one of these is a document. Not the droid we're looking for.
4254                    continue;
4255                }
4256            }
4257
4258            if (!doTrim) {
4259                // If the caller is not actually asking for a trim, just tell them we reached
4260                // a point where the trim would happen.
4261                return i;
4262            }
4263
4264            // Either task and tr are the same or, their affinities match or their intents match
4265            // and neither of them is a document, or they are documents using the same activity
4266            // and their maxRecents has been reached.
4267            tr.disposeThumbnail();
4268            mRecentTasks.remove(i);
4269            if (task != tr) {
4270                tr.removedFromRecents(mTaskPersister);
4271            }
4272            i--;
4273            N--;
4274            if (task.intent == null) {
4275                // If the new recent task we are adding is not fully
4276                // specified, then replace it with the existing recent task.
4277                task = tr;
4278            }
4279            notifyTaskPersisterLocked(tr, false);
4280        }
4281
4282        return -1;
4283    }
4284
4285    @Override
4286    public void reportActivityFullyDrawn(IBinder token) {
4287        synchronized (this) {
4288            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4289            if (r == null) {
4290                return;
4291            }
4292            r.reportFullyDrawnLocked();
4293        }
4294    }
4295
4296    @Override
4297    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4298        synchronized (this) {
4299            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4300            if (r == null) {
4301                return;
4302            }
4303            final long origId = Binder.clearCallingIdentity();
4304            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4305            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4306                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4307            if (config != null) {
4308                r.frozenBeforeDestroy = true;
4309                if (!updateConfigurationLocked(config, r, false, false)) {
4310                    mStackSupervisor.resumeTopActivitiesLocked();
4311                }
4312            }
4313            Binder.restoreCallingIdentity(origId);
4314        }
4315    }
4316
4317    @Override
4318    public int getRequestedOrientation(IBinder token) {
4319        synchronized (this) {
4320            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4321            if (r == null) {
4322                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4323            }
4324            return mWindowManager.getAppOrientation(r.appToken);
4325        }
4326    }
4327
4328    /**
4329     * This is the internal entry point for handling Activity.finish().
4330     *
4331     * @param token The Binder token referencing the Activity we want to finish.
4332     * @param resultCode Result code, if any, from this Activity.
4333     * @param resultData Result data (Intent), if any, from this Activity.
4334     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4335     *            the root Activity in the task.
4336     *
4337     * @return Returns true if the activity successfully finished, or false if it is still running.
4338     */
4339    @Override
4340    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4341            boolean finishTask) {
4342        // Refuse possible leaked file descriptors
4343        if (resultData != null && resultData.hasFileDescriptors() == true) {
4344            throw new IllegalArgumentException("File descriptors passed in Intent");
4345        }
4346
4347        synchronized(this) {
4348            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4349            if (r == null) {
4350                return true;
4351            }
4352            // Keep track of the root activity of the task before we finish it
4353            TaskRecord tr = r.task;
4354            ActivityRecord rootR = tr.getRootActivity();
4355            // Do not allow task to finish in Lock Task mode.
4356            if (tr == mStackSupervisor.mLockTaskModeTask) {
4357                if (rootR == r) {
4358                    mStackSupervisor.showLockTaskToast();
4359                    return false;
4360                }
4361            }
4362            if (mController != null) {
4363                // Find the first activity that is not finishing.
4364                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4365                if (next != null) {
4366                    // ask watcher if this is allowed
4367                    boolean resumeOK = true;
4368                    try {
4369                        resumeOK = mController.activityResuming(next.packageName);
4370                    } catch (RemoteException e) {
4371                        mController = null;
4372                        Watchdog.getInstance().setActivityController(null);
4373                    }
4374
4375                    if (!resumeOK) {
4376                        return false;
4377                    }
4378                }
4379            }
4380            final long origId = Binder.clearCallingIdentity();
4381            try {
4382                boolean res;
4383                if (finishTask && r == rootR) {
4384                    // If requested, remove the task that is associated to this activity only if it
4385                    // was the root activity in the task.  The result code and data is ignored because
4386                    // we don't support returning them across task boundaries.
4387                    res = removeTaskByIdLocked(tr.taskId, 0);
4388                } else {
4389                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4390                            resultData, "app-request", true);
4391                }
4392                return res;
4393            } finally {
4394                Binder.restoreCallingIdentity(origId);
4395            }
4396        }
4397    }
4398
4399    @Override
4400    public final void finishHeavyWeightApp() {
4401        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4402                != PackageManager.PERMISSION_GRANTED) {
4403            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4404                    + Binder.getCallingPid()
4405                    + ", uid=" + Binder.getCallingUid()
4406                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4407            Slog.w(TAG, msg);
4408            throw new SecurityException(msg);
4409        }
4410
4411        synchronized(this) {
4412            if (mHeavyWeightProcess == null) {
4413                return;
4414            }
4415
4416            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4417                    mHeavyWeightProcess.activities);
4418            for (int i=0; i<activities.size(); i++) {
4419                ActivityRecord r = activities.get(i);
4420                if (!r.finishing) {
4421                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4422                            null, "finish-heavy", true);
4423                }
4424            }
4425
4426            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4427                    mHeavyWeightProcess.userId, 0));
4428            mHeavyWeightProcess = null;
4429        }
4430    }
4431
4432    @Override
4433    public void crashApplication(int uid, int initialPid, String packageName,
4434            String message) {
4435        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4436                != PackageManager.PERMISSION_GRANTED) {
4437            String msg = "Permission Denial: crashApplication() from pid="
4438                    + Binder.getCallingPid()
4439                    + ", uid=" + Binder.getCallingUid()
4440                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4441            Slog.w(TAG, msg);
4442            throw new SecurityException(msg);
4443        }
4444
4445        synchronized(this) {
4446            ProcessRecord proc = null;
4447
4448            // Figure out which process to kill.  We don't trust that initialPid
4449            // still has any relation to current pids, so must scan through the
4450            // list.
4451            synchronized (mPidsSelfLocked) {
4452                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4453                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4454                    if (p.uid != uid) {
4455                        continue;
4456                    }
4457                    if (p.pid == initialPid) {
4458                        proc = p;
4459                        break;
4460                    }
4461                    if (p.pkgList.containsKey(packageName)) {
4462                        proc = p;
4463                    }
4464                }
4465            }
4466
4467            if (proc == null) {
4468                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4469                        + " initialPid=" + initialPid
4470                        + " packageName=" + packageName);
4471                return;
4472            }
4473
4474            if (proc.thread != null) {
4475                if (proc.pid == Process.myPid()) {
4476                    Log.w(TAG, "crashApplication: trying to crash self!");
4477                    return;
4478                }
4479                long ident = Binder.clearCallingIdentity();
4480                try {
4481                    proc.thread.scheduleCrash(message);
4482                } catch (RemoteException e) {
4483                }
4484                Binder.restoreCallingIdentity(ident);
4485            }
4486        }
4487    }
4488
4489    @Override
4490    public final void finishSubActivity(IBinder token, String resultWho,
4491            int requestCode) {
4492        synchronized(this) {
4493            final long origId = Binder.clearCallingIdentity();
4494            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4495            if (r != null) {
4496                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4497            }
4498            Binder.restoreCallingIdentity(origId);
4499        }
4500    }
4501
4502    @Override
4503    public boolean finishActivityAffinity(IBinder token) {
4504        synchronized(this) {
4505            final long origId = Binder.clearCallingIdentity();
4506            try {
4507                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4508
4509                ActivityRecord rootR = r.task.getRootActivity();
4510                // Do not allow task to finish in Lock Task mode.
4511                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4512                    if (rootR == r) {
4513                        mStackSupervisor.showLockTaskToast();
4514                        return false;
4515                    }
4516                }
4517                boolean res = false;
4518                if (r != null) {
4519                    res = r.task.stack.finishActivityAffinityLocked(r);
4520                }
4521                return res;
4522            } finally {
4523                Binder.restoreCallingIdentity(origId);
4524            }
4525        }
4526    }
4527
4528    @Override
4529    public void finishVoiceTask(IVoiceInteractionSession session) {
4530        synchronized(this) {
4531            final long origId = Binder.clearCallingIdentity();
4532            try {
4533                mStackSupervisor.finishVoiceTask(session);
4534            } finally {
4535                Binder.restoreCallingIdentity(origId);
4536            }
4537        }
4538
4539    }
4540
4541    @Override
4542    public boolean releaseActivityInstance(IBinder token) {
4543        synchronized(this) {
4544            final long origId = Binder.clearCallingIdentity();
4545            try {
4546                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4547                if (r.task == null || r.task.stack == null) {
4548                    return false;
4549                }
4550                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4551            } finally {
4552                Binder.restoreCallingIdentity(origId);
4553            }
4554        }
4555    }
4556
4557    @Override
4558    public void releaseSomeActivities(IApplicationThread appInt) {
4559        synchronized(this) {
4560            final long origId = Binder.clearCallingIdentity();
4561            try {
4562                ProcessRecord app = getRecordForAppLocked(appInt);
4563                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4564            } finally {
4565                Binder.restoreCallingIdentity(origId);
4566            }
4567        }
4568    }
4569
4570    @Override
4571    public boolean willActivityBeVisible(IBinder token) {
4572        synchronized(this) {
4573            ActivityStack stack = ActivityRecord.getStackLocked(token);
4574            if (stack != null) {
4575                return stack.willActivityBeVisibleLocked(token);
4576            }
4577            return false;
4578        }
4579    }
4580
4581    @Override
4582    public void overridePendingTransition(IBinder token, String packageName,
4583            int enterAnim, int exitAnim) {
4584        synchronized(this) {
4585            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4586            if (self == null) {
4587                return;
4588            }
4589
4590            final long origId = Binder.clearCallingIdentity();
4591
4592            if (self.state == ActivityState.RESUMED
4593                    || self.state == ActivityState.PAUSING) {
4594                mWindowManager.overridePendingAppTransition(packageName,
4595                        enterAnim, exitAnim, null);
4596            }
4597
4598            Binder.restoreCallingIdentity(origId);
4599        }
4600    }
4601
4602    /**
4603     * Main function for removing an existing process from the activity manager
4604     * as a result of that process going away.  Clears out all connections
4605     * to the process.
4606     */
4607    private final void handleAppDiedLocked(ProcessRecord app,
4608            boolean restarting, boolean allowRestart) {
4609        int pid = app.pid;
4610        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4611        if (!restarting) {
4612            removeLruProcessLocked(app);
4613            if (pid > 0) {
4614                ProcessList.remove(pid);
4615            }
4616        }
4617
4618        if (mProfileProc == app) {
4619            clearProfilerLocked();
4620        }
4621
4622        // Remove this application's activities from active lists.
4623        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4624
4625        app.activities.clear();
4626
4627        if (app.instrumentationClass != null) {
4628            Slog.w(TAG, "Crash of app " + app.processName
4629                  + " running instrumentation " + app.instrumentationClass);
4630            Bundle info = new Bundle();
4631            info.putString("shortMsg", "Process crashed.");
4632            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4633        }
4634
4635        if (!restarting) {
4636            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4637                // If there was nothing to resume, and we are not already
4638                // restarting this process, but there is a visible activity that
4639                // is hosted by the process...  then make sure all visible
4640                // activities are running, taking care of restarting this
4641                // process.
4642                if (hasVisibleActivities) {
4643                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4644                }
4645            }
4646        }
4647    }
4648
4649    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4650        IBinder threadBinder = thread.asBinder();
4651        // Find the application record.
4652        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4653            ProcessRecord rec = mLruProcesses.get(i);
4654            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4655                return i;
4656            }
4657        }
4658        return -1;
4659    }
4660
4661    final ProcessRecord getRecordForAppLocked(
4662            IApplicationThread thread) {
4663        if (thread == null) {
4664            return null;
4665        }
4666
4667        int appIndex = getLRURecordIndexForAppLocked(thread);
4668        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4669    }
4670
4671    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4672        // If there are no longer any background processes running,
4673        // and the app that died was not running instrumentation,
4674        // then tell everyone we are now low on memory.
4675        boolean haveBg = false;
4676        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4677            ProcessRecord rec = mLruProcesses.get(i);
4678            if (rec.thread != null
4679                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4680                haveBg = true;
4681                break;
4682            }
4683        }
4684
4685        if (!haveBg) {
4686            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4687            if (doReport) {
4688                long now = SystemClock.uptimeMillis();
4689                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4690                    doReport = false;
4691                } else {
4692                    mLastMemUsageReportTime = now;
4693                }
4694            }
4695            final ArrayList<ProcessMemInfo> memInfos
4696                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4697            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4698            long now = SystemClock.uptimeMillis();
4699            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4700                ProcessRecord rec = mLruProcesses.get(i);
4701                if (rec == dyingProc || rec.thread == null) {
4702                    continue;
4703                }
4704                if (doReport) {
4705                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4706                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4707                }
4708                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4709                    // The low memory report is overriding any current
4710                    // state for a GC request.  Make sure to do
4711                    // heavy/important/visible/foreground processes first.
4712                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4713                        rec.lastRequestedGc = 0;
4714                    } else {
4715                        rec.lastRequestedGc = rec.lastLowMemory;
4716                    }
4717                    rec.reportLowMemory = true;
4718                    rec.lastLowMemory = now;
4719                    mProcessesToGc.remove(rec);
4720                    addProcessToGcListLocked(rec);
4721                }
4722            }
4723            if (doReport) {
4724                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4725                mHandler.sendMessage(msg);
4726            }
4727            scheduleAppGcsLocked();
4728        }
4729    }
4730
4731    final void appDiedLocked(ProcessRecord app) {
4732       appDiedLocked(app, app.pid, app.thread);
4733    }
4734
4735    final void appDiedLocked(ProcessRecord app, int pid,
4736            IApplicationThread thread) {
4737
4738        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4739        synchronized (stats) {
4740            stats.noteProcessDiedLocked(app.info.uid, pid);
4741        }
4742
4743        Process.killProcessGroup(app.info.uid, pid);
4744
4745        // Clean up already done if the process has been re-started.
4746        if (app.pid == pid && app.thread != null &&
4747                app.thread.asBinder() == thread.asBinder()) {
4748            boolean doLowMem = app.instrumentationClass == null;
4749            boolean doOomAdj = doLowMem;
4750            if (!app.killedByAm) {
4751                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4752                        + ") has died.");
4753                mAllowLowerMemLevel = true;
4754            } else {
4755                // Note that we always want to do oom adj to update our state with the
4756                // new number of procs.
4757                mAllowLowerMemLevel = false;
4758                doLowMem = false;
4759            }
4760            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4761            if (DEBUG_CLEANUP) Slog.v(
4762                TAG, "Dying app: " + app + ", pid: " + pid
4763                + ", thread: " + thread.asBinder());
4764            handleAppDiedLocked(app, false, true);
4765
4766            if (doOomAdj) {
4767                updateOomAdjLocked();
4768            }
4769            if (doLowMem) {
4770                doLowMemReportIfNeededLocked(app);
4771            }
4772        } else if (app.pid != pid) {
4773            // A new process has already been started.
4774            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4775                    + ") has died and restarted (pid " + app.pid + ").");
4776            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4777        } else if (DEBUG_PROCESSES) {
4778            Slog.d(TAG, "Received spurious death notification for thread "
4779                    + thread.asBinder());
4780        }
4781    }
4782
4783    /**
4784     * If a stack trace dump file is configured, dump process stack traces.
4785     * @param clearTraces causes the dump file to be erased prior to the new
4786     *    traces being written, if true; when false, the new traces will be
4787     *    appended to any existing file content.
4788     * @param firstPids of dalvik VM processes to dump stack traces for first
4789     * @param lastPids of dalvik VM processes to dump stack traces for last
4790     * @param nativeProcs optional list of native process names to dump stack crawls
4791     * @return file containing stack traces, or null if no dump file is configured
4792     */
4793    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4794            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4795        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4796        if (tracesPath == null || tracesPath.length() == 0) {
4797            return null;
4798        }
4799
4800        File tracesFile = new File(tracesPath);
4801        try {
4802            File tracesDir = tracesFile.getParentFile();
4803            if (!tracesDir.exists()) {
4804                tracesFile.mkdirs();
4805                if (!SELinux.restorecon(tracesDir)) {
4806                    return null;
4807                }
4808            }
4809            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4810
4811            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4812            tracesFile.createNewFile();
4813            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4814        } catch (IOException e) {
4815            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4816            return null;
4817        }
4818
4819        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4820        return tracesFile;
4821    }
4822
4823    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4824            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4825        // Use a FileObserver to detect when traces finish writing.
4826        // The order of traces is considered important to maintain for legibility.
4827        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4828            @Override
4829            public synchronized void onEvent(int event, String path) { notify(); }
4830        };
4831
4832        try {
4833            observer.startWatching();
4834
4835            // First collect all of the stacks of the most important pids.
4836            if (firstPids != null) {
4837                try {
4838                    int num = firstPids.size();
4839                    for (int i = 0; i < num; i++) {
4840                        synchronized (observer) {
4841                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4842                            observer.wait(200);  // Wait for write-close, give up after 200msec
4843                        }
4844                    }
4845                } catch (InterruptedException e) {
4846                    Log.wtf(TAG, e);
4847                }
4848            }
4849
4850            // Next collect the stacks of the native pids
4851            if (nativeProcs != null) {
4852                int[] pids = Process.getPidsForCommands(nativeProcs);
4853                if (pids != null) {
4854                    for (int pid : pids) {
4855                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4856                    }
4857                }
4858            }
4859
4860            // Lastly, measure CPU usage.
4861            if (processCpuTracker != null) {
4862                processCpuTracker.init();
4863                System.gc();
4864                processCpuTracker.update();
4865                try {
4866                    synchronized (processCpuTracker) {
4867                        processCpuTracker.wait(500); // measure over 1/2 second.
4868                    }
4869                } catch (InterruptedException e) {
4870                }
4871                processCpuTracker.update();
4872
4873                // We'll take the stack crawls of just the top apps using CPU.
4874                final int N = processCpuTracker.countWorkingStats();
4875                int numProcs = 0;
4876                for (int i=0; i<N && numProcs<5; i++) {
4877                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4878                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4879                        numProcs++;
4880                        try {
4881                            synchronized (observer) {
4882                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4883                                observer.wait(200);  // Wait for write-close, give up after 200msec
4884                            }
4885                        } catch (InterruptedException e) {
4886                            Log.wtf(TAG, e);
4887                        }
4888
4889                    }
4890                }
4891            }
4892        } finally {
4893            observer.stopWatching();
4894        }
4895    }
4896
4897    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4898        if (true || IS_USER_BUILD) {
4899            return;
4900        }
4901        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4902        if (tracesPath == null || tracesPath.length() == 0) {
4903            return;
4904        }
4905
4906        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4907        StrictMode.allowThreadDiskWrites();
4908        try {
4909            final File tracesFile = new File(tracesPath);
4910            final File tracesDir = tracesFile.getParentFile();
4911            final File tracesTmp = new File(tracesDir, "__tmp__");
4912            try {
4913                if (!tracesDir.exists()) {
4914                    tracesFile.mkdirs();
4915                    if (!SELinux.restorecon(tracesDir.getPath())) {
4916                        return;
4917                    }
4918                }
4919                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4920
4921                if (tracesFile.exists()) {
4922                    tracesTmp.delete();
4923                    tracesFile.renameTo(tracesTmp);
4924                }
4925                StringBuilder sb = new StringBuilder();
4926                Time tobj = new Time();
4927                tobj.set(System.currentTimeMillis());
4928                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4929                sb.append(": ");
4930                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4931                sb.append(" since ");
4932                sb.append(msg);
4933                FileOutputStream fos = new FileOutputStream(tracesFile);
4934                fos.write(sb.toString().getBytes());
4935                if (app == null) {
4936                    fos.write("\n*** No application process!".getBytes());
4937                }
4938                fos.close();
4939                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4940            } catch (IOException e) {
4941                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4942                return;
4943            }
4944
4945            if (app != null) {
4946                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4947                firstPids.add(app.pid);
4948                dumpStackTraces(tracesPath, firstPids, null, null, null);
4949            }
4950
4951            File lastTracesFile = null;
4952            File curTracesFile = null;
4953            for (int i=9; i>=0; i--) {
4954                String name = String.format(Locale.US, "slow%02d.txt", i);
4955                curTracesFile = new File(tracesDir, name);
4956                if (curTracesFile.exists()) {
4957                    if (lastTracesFile != null) {
4958                        curTracesFile.renameTo(lastTracesFile);
4959                    } else {
4960                        curTracesFile.delete();
4961                    }
4962                }
4963                lastTracesFile = curTracesFile;
4964            }
4965            tracesFile.renameTo(curTracesFile);
4966            if (tracesTmp.exists()) {
4967                tracesTmp.renameTo(tracesFile);
4968            }
4969        } finally {
4970            StrictMode.setThreadPolicy(oldPolicy);
4971        }
4972    }
4973
4974    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4975            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4976        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4977        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4978
4979        if (mController != null) {
4980            try {
4981                // 0 == continue, -1 = kill process immediately
4982                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4983                if (res < 0 && app.pid != MY_PID) {
4984                    app.kill("anr", true);
4985                }
4986            } catch (RemoteException e) {
4987                mController = null;
4988                Watchdog.getInstance().setActivityController(null);
4989            }
4990        }
4991
4992        long anrTime = SystemClock.uptimeMillis();
4993        if (MONITOR_CPU_USAGE) {
4994            updateCpuStatsNow();
4995        }
4996
4997        synchronized (this) {
4998            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4999            if (mShuttingDown) {
5000                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
5001                return;
5002            } else if (app.notResponding) {
5003                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
5004                return;
5005            } else if (app.crashing) {
5006                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
5007                return;
5008            }
5009
5010            // In case we come through here for the same app before completing
5011            // this one, mark as anring now so we will bail out.
5012            app.notResponding = true;
5013
5014            // Log the ANR to the event log.
5015            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
5016                    app.processName, app.info.flags, annotation);
5017
5018            // Dump thread traces as quickly as we can, starting with "interesting" processes.
5019            firstPids.add(app.pid);
5020
5021            int parentPid = app.pid;
5022            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
5023            if (parentPid != app.pid) firstPids.add(parentPid);
5024
5025            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5026
5027            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5028                ProcessRecord r = mLruProcesses.get(i);
5029                if (r != null && r.thread != null) {
5030                    int pid = r.pid;
5031                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5032                        if (r.persistent) {
5033                            firstPids.add(pid);
5034                        } else {
5035                            lastPids.put(pid, Boolean.TRUE);
5036                        }
5037                    }
5038                }
5039            }
5040        }
5041
5042        // Log the ANR to the main log.
5043        StringBuilder info = new StringBuilder();
5044        info.setLength(0);
5045        info.append("ANR in ").append(app.processName);
5046        if (activity != null && activity.shortComponentName != null) {
5047            info.append(" (").append(activity.shortComponentName).append(")");
5048        }
5049        info.append("\n");
5050        info.append("PID: ").append(app.pid).append("\n");
5051        if (annotation != null) {
5052            info.append("Reason: ").append(annotation).append("\n");
5053        }
5054        if (parent != null && parent != activity) {
5055            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5056        }
5057
5058        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5059
5060        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5061                NATIVE_STACKS_OF_INTEREST);
5062
5063        String cpuInfo = null;
5064        if (MONITOR_CPU_USAGE) {
5065            updateCpuStatsNow();
5066            synchronized (mProcessCpuThread) {
5067                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5068            }
5069            info.append(processCpuTracker.printCurrentLoad());
5070            info.append(cpuInfo);
5071        }
5072
5073        info.append(processCpuTracker.printCurrentState(anrTime));
5074
5075        Slog.e(TAG, info.toString());
5076        if (tracesFile == null) {
5077            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5078            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5079        }
5080
5081        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5082                cpuInfo, tracesFile, null);
5083
5084        if (mController != null) {
5085            try {
5086                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5087                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5088                if (res != 0) {
5089                    if (res < 0 && app.pid != MY_PID) {
5090                        app.kill("anr", true);
5091                    } else {
5092                        synchronized (this) {
5093                            mServices.scheduleServiceTimeoutLocked(app);
5094                        }
5095                    }
5096                    return;
5097                }
5098            } catch (RemoteException e) {
5099                mController = null;
5100                Watchdog.getInstance().setActivityController(null);
5101            }
5102        }
5103
5104        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5105        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5106                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5107
5108        synchronized (this) {
5109            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5110                app.kill("bg anr", true);
5111                return;
5112            }
5113
5114            // Set the app's notResponding state, and look up the errorReportReceiver
5115            makeAppNotRespondingLocked(app,
5116                    activity != null ? activity.shortComponentName : null,
5117                    annotation != null ? "ANR " + annotation : "ANR",
5118                    info.toString());
5119
5120            // Bring up the infamous App Not Responding dialog
5121            Message msg = Message.obtain();
5122            HashMap<String, Object> map = new HashMap<String, Object>();
5123            msg.what = SHOW_NOT_RESPONDING_MSG;
5124            msg.obj = map;
5125            msg.arg1 = aboveSystem ? 1 : 0;
5126            map.put("app", app);
5127            if (activity != null) {
5128                map.put("activity", activity);
5129            }
5130
5131            mHandler.sendMessage(msg);
5132        }
5133    }
5134
5135    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5136        if (!mLaunchWarningShown) {
5137            mLaunchWarningShown = true;
5138            mHandler.post(new Runnable() {
5139                @Override
5140                public void run() {
5141                    synchronized (ActivityManagerService.this) {
5142                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5143                        d.show();
5144                        mHandler.postDelayed(new Runnable() {
5145                            @Override
5146                            public void run() {
5147                                synchronized (ActivityManagerService.this) {
5148                                    d.dismiss();
5149                                    mLaunchWarningShown = false;
5150                                }
5151                            }
5152                        }, 4000);
5153                    }
5154                }
5155            });
5156        }
5157    }
5158
5159    @Override
5160    public boolean clearApplicationUserData(final String packageName,
5161            final IPackageDataObserver observer, int userId) {
5162        enforceNotIsolatedCaller("clearApplicationUserData");
5163        int uid = Binder.getCallingUid();
5164        int pid = Binder.getCallingPid();
5165        userId = handleIncomingUser(pid, uid,
5166                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5167        long callingId = Binder.clearCallingIdentity();
5168        try {
5169            IPackageManager pm = AppGlobals.getPackageManager();
5170            int pkgUid = -1;
5171            synchronized(this) {
5172                try {
5173                    pkgUid = pm.getPackageUid(packageName, userId);
5174                } catch (RemoteException e) {
5175                }
5176                if (pkgUid == -1) {
5177                    Slog.w(TAG, "Invalid packageName: " + packageName);
5178                    if (observer != null) {
5179                        try {
5180                            observer.onRemoveCompleted(packageName, false);
5181                        } catch (RemoteException e) {
5182                            Slog.i(TAG, "Observer no longer exists.");
5183                        }
5184                    }
5185                    return false;
5186                }
5187                if (uid == pkgUid || checkComponentPermission(
5188                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5189                        pid, uid, -1, true)
5190                        == PackageManager.PERMISSION_GRANTED) {
5191                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5192                } else {
5193                    throw new SecurityException("PID " + pid + " does not have permission "
5194                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5195                                    + " of package " + packageName);
5196                }
5197
5198                // Remove all tasks match the cleared application package and user
5199                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5200                    final TaskRecord tr = mRecentTasks.get(i);
5201                    final String taskPackageName =
5202                            tr.getBaseIntent().getComponent().getPackageName();
5203                    if (tr.userId != userId) continue;
5204                    if (!taskPackageName.equals(packageName)) continue;
5205                    removeTaskByIdLocked(tr.taskId, 0);
5206                }
5207            }
5208
5209            try {
5210                // Clear application user data
5211                pm.clearApplicationUserData(packageName, observer, userId);
5212
5213                synchronized(this) {
5214                    // Remove all permissions granted from/to this package
5215                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5216                }
5217
5218                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5219                        Uri.fromParts("package", packageName, null));
5220                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5221                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5222                        null, null, 0, null, null, null, false, false, userId);
5223            } catch (RemoteException e) {
5224            }
5225        } finally {
5226            Binder.restoreCallingIdentity(callingId);
5227        }
5228        return true;
5229    }
5230
5231    @Override
5232    public void killBackgroundProcesses(final String packageName, int userId) {
5233        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5234                != PackageManager.PERMISSION_GRANTED &&
5235                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5236                        != PackageManager.PERMISSION_GRANTED) {
5237            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5238                    + Binder.getCallingPid()
5239                    + ", uid=" + Binder.getCallingUid()
5240                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5241            Slog.w(TAG, msg);
5242            throw new SecurityException(msg);
5243        }
5244
5245        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5246                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5247        long callingId = Binder.clearCallingIdentity();
5248        try {
5249            IPackageManager pm = AppGlobals.getPackageManager();
5250            synchronized(this) {
5251                int appId = -1;
5252                try {
5253                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5254                } catch (RemoteException e) {
5255                }
5256                if (appId == -1) {
5257                    Slog.w(TAG, "Invalid packageName: " + packageName);
5258                    return;
5259                }
5260                killPackageProcessesLocked(packageName, appId, userId,
5261                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5262            }
5263        } finally {
5264            Binder.restoreCallingIdentity(callingId);
5265        }
5266    }
5267
5268    @Override
5269    public void killAllBackgroundProcesses() {
5270        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5271                != PackageManager.PERMISSION_GRANTED) {
5272            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5273                    + Binder.getCallingPid()
5274                    + ", uid=" + Binder.getCallingUid()
5275                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5276            Slog.w(TAG, msg);
5277            throw new SecurityException(msg);
5278        }
5279
5280        long callingId = Binder.clearCallingIdentity();
5281        try {
5282            synchronized(this) {
5283                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5284                final int NP = mProcessNames.getMap().size();
5285                for (int ip=0; ip<NP; ip++) {
5286                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5287                    final int NA = apps.size();
5288                    for (int ia=0; ia<NA; ia++) {
5289                        ProcessRecord app = apps.valueAt(ia);
5290                        if (app.persistent) {
5291                            // we don't kill persistent processes
5292                            continue;
5293                        }
5294                        if (app.removed) {
5295                            procs.add(app);
5296                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5297                            app.removed = true;
5298                            procs.add(app);
5299                        }
5300                    }
5301                }
5302
5303                int N = procs.size();
5304                for (int i=0; i<N; i++) {
5305                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5306                }
5307                mAllowLowerMemLevel = true;
5308                updateOomAdjLocked();
5309                doLowMemReportIfNeededLocked(null);
5310            }
5311        } finally {
5312            Binder.restoreCallingIdentity(callingId);
5313        }
5314    }
5315
5316    @Override
5317    public void forceStopPackage(final String packageName, int userId) {
5318        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5319                != PackageManager.PERMISSION_GRANTED) {
5320            String msg = "Permission Denial: forceStopPackage() from pid="
5321                    + Binder.getCallingPid()
5322                    + ", uid=" + Binder.getCallingUid()
5323                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5324            Slog.w(TAG, msg);
5325            throw new SecurityException(msg);
5326        }
5327        final int callingPid = Binder.getCallingPid();
5328        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5329                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5330        long callingId = Binder.clearCallingIdentity();
5331        try {
5332            IPackageManager pm = AppGlobals.getPackageManager();
5333            synchronized(this) {
5334                int[] users = userId == UserHandle.USER_ALL
5335                        ? getUsersLocked() : new int[] { userId };
5336                for (int user : users) {
5337                    int pkgUid = -1;
5338                    try {
5339                        pkgUid = pm.getPackageUid(packageName, user);
5340                    } catch (RemoteException e) {
5341                    }
5342                    if (pkgUid == -1) {
5343                        Slog.w(TAG, "Invalid packageName: " + packageName);
5344                        continue;
5345                    }
5346                    try {
5347                        pm.setPackageStoppedState(packageName, true, user);
5348                    } catch (RemoteException e) {
5349                    } catch (IllegalArgumentException e) {
5350                        Slog.w(TAG, "Failed trying to unstop package "
5351                                + packageName + ": " + e);
5352                    }
5353                    if (isUserRunningLocked(user, false)) {
5354                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5355                    }
5356                }
5357            }
5358        } finally {
5359            Binder.restoreCallingIdentity(callingId);
5360        }
5361    }
5362
5363    @Override
5364    public void addPackageDependency(String packageName) {
5365        synchronized (this) {
5366            int callingPid = Binder.getCallingPid();
5367            if (callingPid == Process.myPid()) {
5368                //  Yeah, um, no.
5369                Slog.w(TAG, "Can't addPackageDependency on system process");
5370                return;
5371            }
5372            ProcessRecord proc;
5373            synchronized (mPidsSelfLocked) {
5374                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5375            }
5376            if (proc != null) {
5377                if (proc.pkgDeps == null) {
5378                    proc.pkgDeps = new ArraySet<String>(1);
5379                }
5380                proc.pkgDeps.add(packageName);
5381            }
5382        }
5383    }
5384
5385    /*
5386     * The pkg name and app id have to be specified.
5387     */
5388    @Override
5389    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5390        if (pkg == null) {
5391            return;
5392        }
5393        // Make sure the uid is valid.
5394        if (appid < 0) {
5395            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5396            return;
5397        }
5398        int callerUid = Binder.getCallingUid();
5399        // Only the system server can kill an application
5400        if (callerUid == Process.SYSTEM_UID) {
5401            // Post an aysnc message to kill the application
5402            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5403            msg.arg1 = appid;
5404            msg.arg2 = 0;
5405            Bundle bundle = new Bundle();
5406            bundle.putString("pkg", pkg);
5407            bundle.putString("reason", reason);
5408            msg.obj = bundle;
5409            mHandler.sendMessage(msg);
5410        } else {
5411            throw new SecurityException(callerUid + " cannot kill pkg: " +
5412                    pkg);
5413        }
5414    }
5415
5416    @Override
5417    public void closeSystemDialogs(String reason) {
5418        enforceNotIsolatedCaller("closeSystemDialogs");
5419
5420        final int pid = Binder.getCallingPid();
5421        final int uid = Binder.getCallingUid();
5422        final long origId = Binder.clearCallingIdentity();
5423        try {
5424            synchronized (this) {
5425                // Only allow this from foreground processes, so that background
5426                // applications can't abuse it to prevent system UI from being shown.
5427                if (uid >= Process.FIRST_APPLICATION_UID) {
5428                    ProcessRecord proc;
5429                    synchronized (mPidsSelfLocked) {
5430                        proc = mPidsSelfLocked.get(pid);
5431                    }
5432                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5433                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5434                                + " from background process " + proc);
5435                        return;
5436                    }
5437                }
5438                closeSystemDialogsLocked(reason);
5439            }
5440        } finally {
5441            Binder.restoreCallingIdentity(origId);
5442        }
5443    }
5444
5445    void closeSystemDialogsLocked(String reason) {
5446        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5447        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5448                | Intent.FLAG_RECEIVER_FOREGROUND);
5449        if (reason != null) {
5450            intent.putExtra("reason", reason);
5451        }
5452        mWindowManager.closeSystemDialogs(reason);
5453
5454        mStackSupervisor.closeSystemDialogsLocked();
5455
5456        broadcastIntentLocked(null, null, intent, null,
5457                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5458                Process.SYSTEM_UID, UserHandle.USER_ALL);
5459    }
5460
5461    @Override
5462    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5463        enforceNotIsolatedCaller("getProcessMemoryInfo");
5464        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5465        for (int i=pids.length-1; i>=0; i--) {
5466            ProcessRecord proc;
5467            int oomAdj;
5468            synchronized (this) {
5469                synchronized (mPidsSelfLocked) {
5470                    proc = mPidsSelfLocked.get(pids[i]);
5471                    oomAdj = proc != null ? proc.setAdj : 0;
5472                }
5473            }
5474            infos[i] = new Debug.MemoryInfo();
5475            Debug.getMemoryInfo(pids[i], infos[i]);
5476            if (proc != null) {
5477                synchronized (this) {
5478                    if (proc.thread != null && proc.setAdj == oomAdj) {
5479                        // Record this for posterity if the process has been stable.
5480                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5481                                infos[i].getTotalUss(), false, proc.pkgList);
5482                    }
5483                }
5484            }
5485        }
5486        return infos;
5487    }
5488
5489    @Override
5490    public long[] getProcessPss(int[] pids) {
5491        enforceNotIsolatedCaller("getProcessPss");
5492        long[] pss = new long[pids.length];
5493        for (int i=pids.length-1; i>=0; i--) {
5494            ProcessRecord proc;
5495            int oomAdj;
5496            synchronized (this) {
5497                synchronized (mPidsSelfLocked) {
5498                    proc = mPidsSelfLocked.get(pids[i]);
5499                    oomAdj = proc != null ? proc.setAdj : 0;
5500                }
5501            }
5502            long[] tmpUss = new long[1];
5503            pss[i] = Debug.getPss(pids[i], tmpUss);
5504            if (proc != null) {
5505                synchronized (this) {
5506                    if (proc.thread != null && proc.setAdj == oomAdj) {
5507                        // Record this for posterity if the process has been stable.
5508                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5509                    }
5510                }
5511            }
5512        }
5513        return pss;
5514    }
5515
5516    @Override
5517    public void killApplicationProcess(String processName, int uid) {
5518        if (processName == null) {
5519            return;
5520        }
5521
5522        int callerUid = Binder.getCallingUid();
5523        // Only the system server can kill an application
5524        if (callerUid == Process.SYSTEM_UID) {
5525            synchronized (this) {
5526                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5527                if (app != null && app.thread != null) {
5528                    try {
5529                        app.thread.scheduleSuicide();
5530                    } catch (RemoteException e) {
5531                        // If the other end already died, then our work here is done.
5532                    }
5533                } else {
5534                    Slog.w(TAG, "Process/uid not found attempting kill of "
5535                            + processName + " / " + uid);
5536                }
5537            }
5538        } else {
5539            throw new SecurityException(callerUid + " cannot kill app process: " +
5540                    processName);
5541        }
5542    }
5543
5544    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5545        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5546                false, true, false, false, UserHandle.getUserId(uid), reason);
5547        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5548                Uri.fromParts("package", packageName, null));
5549        if (!mProcessesReady) {
5550            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5551                    | Intent.FLAG_RECEIVER_FOREGROUND);
5552        }
5553        intent.putExtra(Intent.EXTRA_UID, uid);
5554        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5555        broadcastIntentLocked(null, null, intent,
5556                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5557                false, false,
5558                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5559    }
5560
5561    private void forceStopUserLocked(int userId, String reason) {
5562        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5563        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5564        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5565                | Intent.FLAG_RECEIVER_FOREGROUND);
5566        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5567        broadcastIntentLocked(null, null, intent,
5568                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5569                false, false,
5570                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5571    }
5572
5573    private final boolean killPackageProcessesLocked(String packageName, int appId,
5574            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5575            boolean doit, boolean evenPersistent, String reason) {
5576        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5577
5578        // Remove all processes this package may have touched: all with the
5579        // same UID (except for the system or root user), and all whose name
5580        // matches the package name.
5581        final int NP = mProcessNames.getMap().size();
5582        for (int ip=0; ip<NP; ip++) {
5583            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5584            final int NA = apps.size();
5585            for (int ia=0; ia<NA; ia++) {
5586                ProcessRecord app = apps.valueAt(ia);
5587                if (app.persistent && !evenPersistent) {
5588                    // we don't kill persistent processes
5589                    continue;
5590                }
5591                if (app.removed) {
5592                    if (doit) {
5593                        procs.add(app);
5594                    }
5595                    continue;
5596                }
5597
5598                // Skip process if it doesn't meet our oom adj requirement.
5599                if (app.setAdj < minOomAdj) {
5600                    continue;
5601                }
5602
5603                // If no package is specified, we call all processes under the
5604                // give user id.
5605                if (packageName == null) {
5606                    if (app.userId != userId) {
5607                        continue;
5608                    }
5609                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5610                        continue;
5611                    }
5612                // Package has been specified, we want to hit all processes
5613                // that match it.  We need to qualify this by the processes
5614                // that are running under the specified app and user ID.
5615                } else {
5616                    final boolean isDep = app.pkgDeps != null
5617                            && app.pkgDeps.contains(packageName);
5618                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5619                        continue;
5620                    }
5621                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5622                        continue;
5623                    }
5624                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5625                        continue;
5626                    }
5627                }
5628
5629                // Process has passed all conditions, kill it!
5630                if (!doit) {
5631                    return true;
5632                }
5633                app.removed = true;
5634                procs.add(app);
5635            }
5636        }
5637
5638        int N = procs.size();
5639        for (int i=0; i<N; i++) {
5640            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5641        }
5642        updateOomAdjLocked();
5643        return N > 0;
5644    }
5645
5646    private final boolean forceStopPackageLocked(String name, int appId,
5647            boolean callerWillRestart, boolean purgeCache, boolean doit,
5648            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5649        int i;
5650        int N;
5651
5652        if (userId == UserHandle.USER_ALL && name == null) {
5653            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5654        }
5655
5656        if (appId < 0 && name != null) {
5657            try {
5658                appId = UserHandle.getAppId(
5659                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5660            } catch (RemoteException e) {
5661            }
5662        }
5663
5664        if (doit) {
5665            if (name != null) {
5666                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5667                        + " user=" + userId + ": " + reason);
5668            } else {
5669                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5670            }
5671
5672            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5673            for (int ip=pmap.size()-1; ip>=0; ip--) {
5674                SparseArray<Long> ba = pmap.valueAt(ip);
5675                for (i=ba.size()-1; i>=0; i--) {
5676                    boolean remove = false;
5677                    final int entUid = ba.keyAt(i);
5678                    if (name != null) {
5679                        if (userId == UserHandle.USER_ALL) {
5680                            if (UserHandle.getAppId(entUid) == appId) {
5681                                remove = true;
5682                            }
5683                        } else {
5684                            if (entUid == UserHandle.getUid(userId, appId)) {
5685                                remove = true;
5686                            }
5687                        }
5688                    } else if (UserHandle.getUserId(entUid) == userId) {
5689                        remove = true;
5690                    }
5691                    if (remove) {
5692                        ba.removeAt(i);
5693                    }
5694                }
5695                if (ba.size() == 0) {
5696                    pmap.removeAt(ip);
5697                }
5698            }
5699        }
5700
5701        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5702                -100, callerWillRestart, true, doit, evenPersistent,
5703                name == null ? ("stop user " + userId) : ("stop " + name));
5704
5705        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5706            if (!doit) {
5707                return true;
5708            }
5709            didSomething = true;
5710        }
5711
5712        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5713            if (!doit) {
5714                return true;
5715            }
5716            didSomething = true;
5717        }
5718
5719        if (name == null) {
5720            // Remove all sticky broadcasts from this user.
5721            mStickyBroadcasts.remove(userId);
5722        }
5723
5724        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5725        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5726                userId, providers)) {
5727            if (!doit) {
5728                return true;
5729            }
5730            didSomething = true;
5731        }
5732        N = providers.size();
5733        for (i=0; i<N; i++) {
5734            removeDyingProviderLocked(null, providers.get(i), true);
5735        }
5736
5737        // Remove transient permissions granted from/to this package/user
5738        removeUriPermissionsForPackageLocked(name, userId, false);
5739
5740        if (name == null || uninstalling) {
5741            // Remove pending intents.  For now we only do this when force
5742            // stopping users, because we have some problems when doing this
5743            // for packages -- app widgets are not currently cleaned up for
5744            // such packages, so they can be left with bad pending intents.
5745            if (mIntentSenderRecords.size() > 0) {
5746                Iterator<WeakReference<PendingIntentRecord>> it
5747                        = mIntentSenderRecords.values().iterator();
5748                while (it.hasNext()) {
5749                    WeakReference<PendingIntentRecord> wpir = it.next();
5750                    if (wpir == null) {
5751                        it.remove();
5752                        continue;
5753                    }
5754                    PendingIntentRecord pir = wpir.get();
5755                    if (pir == null) {
5756                        it.remove();
5757                        continue;
5758                    }
5759                    if (name == null) {
5760                        // Stopping user, remove all objects for the user.
5761                        if (pir.key.userId != userId) {
5762                            // Not the same user, skip it.
5763                            continue;
5764                        }
5765                    } else {
5766                        if (UserHandle.getAppId(pir.uid) != appId) {
5767                            // Different app id, skip it.
5768                            continue;
5769                        }
5770                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5771                            // Different user, skip it.
5772                            continue;
5773                        }
5774                        if (!pir.key.packageName.equals(name)) {
5775                            // Different package, skip it.
5776                            continue;
5777                        }
5778                    }
5779                    if (!doit) {
5780                        return true;
5781                    }
5782                    didSomething = true;
5783                    it.remove();
5784                    pir.canceled = true;
5785                    if (pir.key.activity != null) {
5786                        pir.key.activity.pendingResults.remove(pir.ref);
5787                    }
5788                }
5789            }
5790        }
5791
5792        if (doit) {
5793            if (purgeCache && name != null) {
5794                AttributeCache ac = AttributeCache.instance();
5795                if (ac != null) {
5796                    ac.removePackage(name);
5797                }
5798            }
5799            if (mBooted) {
5800                mStackSupervisor.resumeTopActivitiesLocked();
5801                mStackSupervisor.scheduleIdleLocked();
5802            }
5803        }
5804
5805        return didSomething;
5806    }
5807
5808    private final boolean removeProcessLocked(ProcessRecord app,
5809            boolean callerWillRestart, boolean allowRestart, String reason) {
5810        final String name = app.processName;
5811        final int uid = app.uid;
5812        if (DEBUG_PROCESSES) Slog.d(
5813            TAG, "Force removing proc " + app.toShortString() + " (" + name
5814            + "/" + uid + ")");
5815
5816        mProcessNames.remove(name, uid);
5817        mIsolatedProcesses.remove(app.uid);
5818        if (mHeavyWeightProcess == app) {
5819            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5820                    mHeavyWeightProcess.userId, 0));
5821            mHeavyWeightProcess = null;
5822        }
5823        boolean needRestart = false;
5824        if (app.pid > 0 && app.pid != MY_PID) {
5825            int pid = app.pid;
5826            synchronized (mPidsSelfLocked) {
5827                mPidsSelfLocked.remove(pid);
5828                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5829            }
5830            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5831            if (app.isolated) {
5832                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5833            }
5834            app.kill(reason, true);
5835            handleAppDiedLocked(app, true, allowRestart);
5836            removeLruProcessLocked(app);
5837
5838            if (app.persistent && !app.isolated) {
5839                if (!callerWillRestart) {
5840                    addAppLocked(app.info, false, null /* ABI override */);
5841                } else {
5842                    needRestart = true;
5843                }
5844            }
5845        } else {
5846            mRemovedProcesses.add(app);
5847        }
5848
5849        return needRestart;
5850    }
5851
5852    private final void processStartTimedOutLocked(ProcessRecord app) {
5853        final int pid = app.pid;
5854        boolean gone = false;
5855        synchronized (mPidsSelfLocked) {
5856            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5857            if (knownApp != null && knownApp.thread == null) {
5858                mPidsSelfLocked.remove(pid);
5859                gone = true;
5860            }
5861        }
5862
5863        if (gone) {
5864            Slog.w(TAG, "Process " + app + " failed to attach");
5865            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5866                    pid, app.uid, app.processName);
5867            mProcessNames.remove(app.processName, app.uid);
5868            mIsolatedProcesses.remove(app.uid);
5869            if (mHeavyWeightProcess == app) {
5870                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5871                        mHeavyWeightProcess.userId, 0));
5872                mHeavyWeightProcess = null;
5873            }
5874            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5875            if (app.isolated) {
5876                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5877            }
5878            // Take care of any launching providers waiting for this process.
5879            checkAppInLaunchingProvidersLocked(app, true);
5880            // Take care of any services that are waiting for the process.
5881            mServices.processStartTimedOutLocked(app);
5882            app.kill("start timeout", true);
5883            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5884                Slog.w(TAG, "Unattached app died before backup, skipping");
5885                try {
5886                    IBackupManager bm = IBackupManager.Stub.asInterface(
5887                            ServiceManager.getService(Context.BACKUP_SERVICE));
5888                    bm.agentDisconnected(app.info.packageName);
5889                } catch (RemoteException e) {
5890                    // Can't happen; the backup manager is local
5891                }
5892            }
5893            if (isPendingBroadcastProcessLocked(pid)) {
5894                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5895                skipPendingBroadcastLocked(pid);
5896            }
5897        } else {
5898            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5899        }
5900    }
5901
5902    private final boolean attachApplicationLocked(IApplicationThread thread,
5903            int pid) {
5904
5905        // Find the application record that is being attached...  either via
5906        // the pid if we are running in multiple processes, or just pull the
5907        // next app record if we are emulating process with anonymous threads.
5908        ProcessRecord app;
5909        if (pid != MY_PID && pid >= 0) {
5910            synchronized (mPidsSelfLocked) {
5911                app = mPidsSelfLocked.get(pid);
5912            }
5913        } else {
5914            app = null;
5915        }
5916
5917        if (app == null) {
5918            Slog.w(TAG, "No pending application record for pid " + pid
5919                    + " (IApplicationThread " + thread + "); dropping process");
5920            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5921            if (pid > 0 && pid != MY_PID) {
5922                Process.killProcessQuiet(pid);
5923                //TODO: Process.killProcessGroup(app.info.uid, pid);
5924            } else {
5925                try {
5926                    thread.scheduleExit();
5927                } catch (Exception e) {
5928                    // Ignore exceptions.
5929                }
5930            }
5931            return false;
5932        }
5933
5934        // If this application record is still attached to a previous
5935        // process, clean it up now.
5936        if (app.thread != null) {
5937            handleAppDiedLocked(app, true, true);
5938        }
5939
5940        // Tell the process all about itself.
5941
5942        if (localLOGV) Slog.v(
5943                TAG, "Binding process pid " + pid + " to record " + app);
5944
5945        final String processName = app.processName;
5946        try {
5947            AppDeathRecipient adr = new AppDeathRecipient(
5948                    app, pid, thread);
5949            thread.asBinder().linkToDeath(adr, 0);
5950            app.deathRecipient = adr;
5951        } catch (RemoteException e) {
5952            app.resetPackageList(mProcessStats);
5953            startProcessLocked(app, "link fail", processName);
5954            return false;
5955        }
5956
5957        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5958
5959        app.makeActive(thread, mProcessStats);
5960        app.curAdj = app.setAdj = -100;
5961        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5962        app.forcingToForeground = null;
5963        updateProcessForegroundLocked(app, false, false);
5964        app.hasShownUi = false;
5965        app.debugging = false;
5966        app.cached = false;
5967
5968        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5969
5970        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5971        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5972
5973        if (!normalMode) {
5974            Slog.i(TAG, "Launching preboot mode app: " + app);
5975        }
5976
5977        if (localLOGV) Slog.v(
5978            TAG, "New app record " + app
5979            + " thread=" + thread.asBinder() + " pid=" + pid);
5980        try {
5981            int testMode = IApplicationThread.DEBUG_OFF;
5982            if (mDebugApp != null && mDebugApp.equals(processName)) {
5983                testMode = mWaitForDebugger
5984                    ? IApplicationThread.DEBUG_WAIT
5985                    : IApplicationThread.DEBUG_ON;
5986                app.debugging = true;
5987                if (mDebugTransient) {
5988                    mDebugApp = mOrigDebugApp;
5989                    mWaitForDebugger = mOrigWaitForDebugger;
5990                }
5991            }
5992            String profileFile = app.instrumentationProfileFile;
5993            ParcelFileDescriptor profileFd = null;
5994            int samplingInterval = 0;
5995            boolean profileAutoStop = false;
5996            if (mProfileApp != null && mProfileApp.equals(processName)) {
5997                mProfileProc = app;
5998                profileFile = mProfileFile;
5999                profileFd = mProfileFd;
6000                samplingInterval = mSamplingInterval;
6001                profileAutoStop = mAutoStopProfiler;
6002            }
6003            boolean enableOpenGlTrace = false;
6004            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
6005                enableOpenGlTrace = true;
6006                mOpenGlTraceApp = null;
6007            }
6008
6009            // If the app is being launched for restore or full backup, set it up specially
6010            boolean isRestrictedBackupMode = false;
6011            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6012                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
6013                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6014                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
6015            }
6016
6017            ensurePackageDexOpt(app.instrumentationInfo != null
6018                    ? app.instrumentationInfo.packageName
6019                    : app.info.packageName);
6020            if (app.instrumentationClass != null) {
6021                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
6022            }
6023            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6024                    + processName + " with config " + mConfiguration);
6025            ApplicationInfo appInfo = app.instrumentationInfo != null
6026                    ? app.instrumentationInfo : app.info;
6027            app.compat = compatibilityInfoForPackageLocked(appInfo);
6028            if (profileFd != null) {
6029                profileFd = profileFd.dup();
6030            }
6031            ProfilerInfo profilerInfo = profileFile == null ? null
6032                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6033            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6034                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6035                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6036                    isRestrictedBackupMode || !normalMode, app.persistent,
6037                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6038                    mCoreSettingsObserver.getCoreSettingsLocked());
6039            updateLruProcessLocked(app, false, null);
6040            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6041        } catch (Exception e) {
6042            // todo: Yikes!  What should we do?  For now we will try to
6043            // start another process, but that could easily get us in
6044            // an infinite loop of restarting processes...
6045            Slog.w(TAG, "Exception thrown during bind!", e);
6046
6047            app.resetPackageList(mProcessStats);
6048            app.unlinkDeathRecipient();
6049            startProcessLocked(app, "bind fail", processName);
6050            return false;
6051        }
6052
6053        // Remove this record from the list of starting applications.
6054        mPersistentStartingProcesses.remove(app);
6055        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6056                "Attach application locked removing on hold: " + app);
6057        mProcessesOnHold.remove(app);
6058
6059        boolean badApp = false;
6060        boolean didSomething = false;
6061
6062        // See if the top visible activity is waiting to run in this process...
6063        if (normalMode) {
6064            try {
6065                if (mStackSupervisor.attachApplicationLocked(app)) {
6066                    didSomething = true;
6067                }
6068            } catch (Exception e) {
6069                badApp = true;
6070            }
6071        }
6072
6073        // Find any services that should be running in this process...
6074        if (!badApp) {
6075            try {
6076                didSomething |= mServices.attachApplicationLocked(app, processName);
6077            } catch (Exception e) {
6078                badApp = true;
6079            }
6080        }
6081
6082        // Check if a next-broadcast receiver is in this process...
6083        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6084            try {
6085                didSomething |= sendPendingBroadcastsLocked(app);
6086            } catch (Exception e) {
6087                // If the app died trying to launch the receiver we declare it 'bad'
6088                badApp = true;
6089            }
6090        }
6091
6092        // Check whether the next backup agent is in this process...
6093        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6094            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6095            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6096            try {
6097                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6098                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6099                        mBackupTarget.backupMode);
6100            } catch (Exception e) {
6101                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6102                e.printStackTrace();
6103            }
6104        }
6105
6106        if (badApp) {
6107            // todo: Also need to kill application to deal with all
6108            // kinds of exceptions.
6109            handleAppDiedLocked(app, false, true);
6110            return false;
6111        }
6112
6113        if (!didSomething) {
6114            updateOomAdjLocked();
6115        }
6116
6117        return true;
6118    }
6119
6120    @Override
6121    public final void attachApplication(IApplicationThread thread) {
6122        synchronized (this) {
6123            int callingPid = Binder.getCallingPid();
6124            final long origId = Binder.clearCallingIdentity();
6125            attachApplicationLocked(thread, callingPid);
6126            Binder.restoreCallingIdentity(origId);
6127        }
6128    }
6129
6130    @Override
6131    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6132        final long origId = Binder.clearCallingIdentity();
6133        synchronized (this) {
6134            ActivityStack stack = ActivityRecord.getStackLocked(token);
6135            if (stack != null) {
6136                ActivityRecord r =
6137                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6138                if (stopProfiling) {
6139                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6140                        try {
6141                            mProfileFd.close();
6142                        } catch (IOException e) {
6143                        }
6144                        clearProfilerLocked();
6145                    }
6146                }
6147            }
6148        }
6149        Binder.restoreCallingIdentity(origId);
6150    }
6151
6152    void postEnableScreenAfterBootLocked() {
6153        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6154    }
6155
6156    void enableScreenAfterBoot() {
6157        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6158                SystemClock.uptimeMillis());
6159        mWindowManager.enableScreenAfterBoot();
6160
6161        synchronized (this) {
6162            updateEventDispatchingLocked();
6163        }
6164    }
6165
6166    @Override
6167    public void showBootMessage(final CharSequence msg, final boolean always) {
6168        enforceNotIsolatedCaller("showBootMessage");
6169        mWindowManager.showBootMessage(msg, always);
6170    }
6171
6172    @Override
6173    public void keyguardWaitingForActivityDrawn() {
6174        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6175        final long token = Binder.clearCallingIdentity();
6176        try {
6177            synchronized (this) {
6178                if (DEBUG_LOCKSCREEN) logLockScreen("");
6179                mWindowManager.keyguardWaitingForActivityDrawn();
6180            }
6181        } finally {
6182            Binder.restoreCallingIdentity(token);
6183        }
6184    }
6185
6186    final void finishBooting() {
6187        // Register receivers to handle package update events
6188        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6189
6190        // Let system services know.
6191        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6192
6193        synchronized (this) {
6194            // Ensure that any processes we had put on hold are now started
6195            // up.
6196            final int NP = mProcessesOnHold.size();
6197            if (NP > 0) {
6198                ArrayList<ProcessRecord> procs =
6199                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6200                for (int ip=0; ip<NP; ip++) {
6201                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6202                            + procs.get(ip));
6203                    startProcessLocked(procs.get(ip), "on-hold", null);
6204                }
6205            }
6206
6207            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6208                // Start looking for apps that are abusing wake locks.
6209                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6210                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6211                // Tell anyone interested that we are done booting!
6212                SystemProperties.set("sys.boot_completed", "1");
6213                SystemProperties.set("dev.bootcomplete", "1");
6214                for (int i=0; i<mStartedUsers.size(); i++) {
6215                    UserStartedState uss = mStartedUsers.valueAt(i);
6216                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6217                        uss.mState = UserStartedState.STATE_RUNNING;
6218                        final int userId = mStartedUsers.keyAt(i);
6219                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6220                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6221                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6222                        broadcastIntentLocked(null, null, intent, null,
6223                                new IIntentReceiver.Stub() {
6224                                    @Override
6225                                    public void performReceive(Intent intent, int resultCode,
6226                                            String data, Bundle extras, boolean ordered,
6227                                            boolean sticky, int sendingUser) {
6228                                        synchronized (ActivityManagerService.this) {
6229                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6230                                                    true, false);
6231                                        }
6232                                    }
6233                                },
6234                                0, null, null,
6235                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6236                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6237                                userId);
6238                    }
6239                }
6240                scheduleStartProfilesLocked();
6241            }
6242        }
6243    }
6244
6245    final void ensureBootCompleted() {
6246        boolean booting;
6247        boolean enableScreen;
6248        synchronized (this) {
6249            booting = mBooting;
6250            mBooting = false;
6251            enableScreen = !mBooted;
6252            mBooted = true;
6253        }
6254
6255        if (booting) {
6256            finishBooting();
6257        }
6258
6259        if (enableScreen) {
6260            enableScreenAfterBoot();
6261        }
6262    }
6263
6264    @Override
6265    public final void activityResumed(IBinder token) {
6266        final long origId = Binder.clearCallingIdentity();
6267        synchronized(this) {
6268            ActivityStack stack = ActivityRecord.getStackLocked(token);
6269            if (stack != null) {
6270                ActivityRecord.activityResumedLocked(token);
6271            }
6272        }
6273        Binder.restoreCallingIdentity(origId);
6274    }
6275
6276    @Override
6277    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
6278        final long origId = Binder.clearCallingIdentity();
6279        synchronized(this) {
6280            ActivityStack stack = ActivityRecord.getStackLocked(token);
6281            if (stack != null) {
6282                stack.activityPausedLocked(token, false, persistentState);
6283            }
6284        }
6285        Binder.restoreCallingIdentity(origId);
6286    }
6287
6288    @Override
6289    public final void activityStopped(IBinder token, Bundle icicle,
6290            PersistableBundle persistentState, CharSequence description) {
6291        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6292
6293        // Refuse possible leaked file descriptors
6294        if (icicle != null && icicle.hasFileDescriptors()) {
6295            throw new IllegalArgumentException("File descriptors passed in Bundle");
6296        }
6297
6298        final long origId = Binder.clearCallingIdentity();
6299
6300        synchronized (this) {
6301            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6302            if (r != null) {
6303                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6304            }
6305        }
6306
6307        trimApplications();
6308
6309        Binder.restoreCallingIdentity(origId);
6310    }
6311
6312    @Override
6313    public final void activityDestroyed(IBinder token) {
6314        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6315        synchronized (this) {
6316            ActivityStack stack = ActivityRecord.getStackLocked(token);
6317            if (stack != null) {
6318                stack.activityDestroyedLocked(token);
6319            }
6320        }
6321    }
6322
6323    @Override
6324    public final void backgroundResourcesReleased(IBinder token) {
6325        final long origId = Binder.clearCallingIdentity();
6326        try {
6327            synchronized (this) {
6328                ActivityStack stack = ActivityRecord.getStackLocked(token);
6329                if (stack != null) {
6330                    stack.backgroundResourcesReleased(token);
6331                }
6332            }
6333        } finally {
6334            Binder.restoreCallingIdentity(origId);
6335        }
6336    }
6337
6338    @Override
6339    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6340        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6341    }
6342
6343    @Override
6344    public final void notifyEnterAnimationComplete(IBinder token) {
6345        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6346    }
6347
6348    @Override
6349    public String getCallingPackage(IBinder token) {
6350        synchronized (this) {
6351            ActivityRecord r = getCallingRecordLocked(token);
6352            return r != null ? r.info.packageName : null;
6353        }
6354    }
6355
6356    @Override
6357    public ComponentName getCallingActivity(IBinder token) {
6358        synchronized (this) {
6359            ActivityRecord r = getCallingRecordLocked(token);
6360            return r != null ? r.intent.getComponent() : null;
6361        }
6362    }
6363
6364    private ActivityRecord getCallingRecordLocked(IBinder token) {
6365        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6366        if (r == null) {
6367            return null;
6368        }
6369        return r.resultTo;
6370    }
6371
6372    @Override
6373    public ComponentName getActivityClassForToken(IBinder token) {
6374        synchronized(this) {
6375            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6376            if (r == null) {
6377                return null;
6378            }
6379            return r.intent.getComponent();
6380        }
6381    }
6382
6383    @Override
6384    public String getPackageForToken(IBinder token) {
6385        synchronized(this) {
6386            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6387            if (r == null) {
6388                return null;
6389            }
6390            return r.packageName;
6391        }
6392    }
6393
6394    @Override
6395    public IIntentSender getIntentSender(int type,
6396            String packageName, IBinder token, String resultWho,
6397            int requestCode, Intent[] intents, String[] resolvedTypes,
6398            int flags, Bundle options, int userId) {
6399        enforceNotIsolatedCaller("getIntentSender");
6400        // Refuse possible leaked file descriptors
6401        if (intents != null) {
6402            if (intents.length < 1) {
6403                throw new IllegalArgumentException("Intents array length must be >= 1");
6404            }
6405            for (int i=0; i<intents.length; i++) {
6406                Intent intent = intents[i];
6407                if (intent != null) {
6408                    if (intent.hasFileDescriptors()) {
6409                        throw new IllegalArgumentException("File descriptors passed in Intent");
6410                    }
6411                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6412                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6413                        throw new IllegalArgumentException(
6414                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6415                    }
6416                    intents[i] = new Intent(intent);
6417                }
6418            }
6419            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6420                throw new IllegalArgumentException(
6421                        "Intent array length does not match resolvedTypes length");
6422            }
6423        }
6424        if (options != null) {
6425            if (options.hasFileDescriptors()) {
6426                throw new IllegalArgumentException("File descriptors passed in options");
6427            }
6428        }
6429
6430        synchronized(this) {
6431            int callingUid = Binder.getCallingUid();
6432            int origUserId = userId;
6433            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6434                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6435                    ALLOW_NON_FULL, "getIntentSender", null);
6436            if (origUserId == UserHandle.USER_CURRENT) {
6437                // We don't want to evaluate this until the pending intent is
6438                // actually executed.  However, we do want to always do the
6439                // security checking for it above.
6440                userId = UserHandle.USER_CURRENT;
6441            }
6442            try {
6443                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6444                    int uid = AppGlobals.getPackageManager()
6445                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6446                    if (!UserHandle.isSameApp(callingUid, uid)) {
6447                        String msg = "Permission Denial: getIntentSender() from pid="
6448                            + Binder.getCallingPid()
6449                            + ", uid=" + Binder.getCallingUid()
6450                            + ", (need uid=" + uid + ")"
6451                            + " is not allowed to send as package " + packageName;
6452                        Slog.w(TAG, msg);
6453                        throw new SecurityException(msg);
6454                    }
6455                }
6456
6457                return getIntentSenderLocked(type, packageName, callingUid, userId,
6458                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6459
6460            } catch (RemoteException e) {
6461                throw new SecurityException(e);
6462            }
6463        }
6464    }
6465
6466    IIntentSender getIntentSenderLocked(int type, String packageName,
6467            int callingUid, int userId, IBinder token, String resultWho,
6468            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6469            Bundle options) {
6470        if (DEBUG_MU)
6471            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6472        ActivityRecord activity = null;
6473        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6474            activity = ActivityRecord.isInStackLocked(token);
6475            if (activity == null) {
6476                return null;
6477            }
6478            if (activity.finishing) {
6479                return null;
6480            }
6481        }
6482
6483        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6484        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6485        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6486        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6487                |PendingIntent.FLAG_UPDATE_CURRENT);
6488
6489        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6490                type, packageName, activity, resultWho,
6491                requestCode, intents, resolvedTypes, flags, options, userId);
6492        WeakReference<PendingIntentRecord> ref;
6493        ref = mIntentSenderRecords.get(key);
6494        PendingIntentRecord rec = ref != null ? ref.get() : null;
6495        if (rec != null) {
6496            if (!cancelCurrent) {
6497                if (updateCurrent) {
6498                    if (rec.key.requestIntent != null) {
6499                        rec.key.requestIntent.replaceExtras(intents != null ?
6500                                intents[intents.length - 1] : null);
6501                    }
6502                    if (intents != null) {
6503                        intents[intents.length-1] = rec.key.requestIntent;
6504                        rec.key.allIntents = intents;
6505                        rec.key.allResolvedTypes = resolvedTypes;
6506                    } else {
6507                        rec.key.allIntents = null;
6508                        rec.key.allResolvedTypes = null;
6509                    }
6510                }
6511                return rec;
6512            }
6513            rec.canceled = true;
6514            mIntentSenderRecords.remove(key);
6515        }
6516        if (noCreate) {
6517            return rec;
6518        }
6519        rec = new PendingIntentRecord(this, key, callingUid);
6520        mIntentSenderRecords.put(key, rec.ref);
6521        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6522            if (activity.pendingResults == null) {
6523                activity.pendingResults
6524                        = new HashSet<WeakReference<PendingIntentRecord>>();
6525            }
6526            activity.pendingResults.add(rec.ref);
6527        }
6528        return rec;
6529    }
6530
6531    @Override
6532    public void cancelIntentSender(IIntentSender sender) {
6533        if (!(sender instanceof PendingIntentRecord)) {
6534            return;
6535        }
6536        synchronized(this) {
6537            PendingIntentRecord rec = (PendingIntentRecord)sender;
6538            try {
6539                int uid = AppGlobals.getPackageManager()
6540                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6541                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6542                    String msg = "Permission Denial: cancelIntentSender() from pid="
6543                        + Binder.getCallingPid()
6544                        + ", uid=" + Binder.getCallingUid()
6545                        + " is not allowed to cancel packges "
6546                        + rec.key.packageName;
6547                    Slog.w(TAG, msg);
6548                    throw new SecurityException(msg);
6549                }
6550            } catch (RemoteException e) {
6551                throw new SecurityException(e);
6552            }
6553            cancelIntentSenderLocked(rec, true);
6554        }
6555    }
6556
6557    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6558        rec.canceled = true;
6559        mIntentSenderRecords.remove(rec.key);
6560        if (cleanActivity && rec.key.activity != null) {
6561            rec.key.activity.pendingResults.remove(rec.ref);
6562        }
6563    }
6564
6565    @Override
6566    public String getPackageForIntentSender(IIntentSender pendingResult) {
6567        if (!(pendingResult instanceof PendingIntentRecord)) {
6568            return null;
6569        }
6570        try {
6571            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6572            return res.key.packageName;
6573        } catch (ClassCastException e) {
6574        }
6575        return null;
6576    }
6577
6578    @Override
6579    public int getUidForIntentSender(IIntentSender sender) {
6580        if (sender instanceof PendingIntentRecord) {
6581            try {
6582                PendingIntentRecord res = (PendingIntentRecord)sender;
6583                return res.uid;
6584            } catch (ClassCastException e) {
6585            }
6586        }
6587        return -1;
6588    }
6589
6590    @Override
6591    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6592        if (!(pendingResult instanceof PendingIntentRecord)) {
6593            return false;
6594        }
6595        try {
6596            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6597            if (res.key.allIntents == null) {
6598                return false;
6599            }
6600            for (int i=0; i<res.key.allIntents.length; i++) {
6601                Intent intent = res.key.allIntents[i];
6602                if (intent.getPackage() != null && intent.getComponent() != null) {
6603                    return false;
6604                }
6605            }
6606            return true;
6607        } catch (ClassCastException e) {
6608        }
6609        return false;
6610    }
6611
6612    @Override
6613    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6614        if (!(pendingResult instanceof PendingIntentRecord)) {
6615            return false;
6616        }
6617        try {
6618            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6619            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6620                return true;
6621            }
6622            return false;
6623        } catch (ClassCastException e) {
6624        }
6625        return false;
6626    }
6627
6628    @Override
6629    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6630        if (!(pendingResult instanceof PendingIntentRecord)) {
6631            return null;
6632        }
6633        try {
6634            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6635            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6636        } catch (ClassCastException e) {
6637        }
6638        return null;
6639    }
6640
6641    @Override
6642    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6643        if (!(pendingResult instanceof PendingIntentRecord)) {
6644            return null;
6645        }
6646        try {
6647            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6648            Intent intent = res.key.requestIntent;
6649            if (intent != null) {
6650                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6651                        || res.lastTagPrefix.equals(prefix))) {
6652                    return res.lastTag;
6653                }
6654                res.lastTagPrefix = prefix;
6655                StringBuilder sb = new StringBuilder(128);
6656                if (prefix != null) {
6657                    sb.append(prefix);
6658                }
6659                if (intent.getAction() != null) {
6660                    sb.append(intent.getAction());
6661                } else if (intent.getComponent() != null) {
6662                    intent.getComponent().appendShortString(sb);
6663                } else {
6664                    sb.append("?");
6665                }
6666                return res.lastTag = sb.toString();
6667            }
6668        } catch (ClassCastException e) {
6669        }
6670        return null;
6671    }
6672
6673    @Override
6674    public void setProcessLimit(int max) {
6675        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6676                "setProcessLimit()");
6677        synchronized (this) {
6678            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6679            mProcessLimitOverride = max;
6680        }
6681        trimApplications();
6682    }
6683
6684    @Override
6685    public int getProcessLimit() {
6686        synchronized (this) {
6687            return mProcessLimitOverride;
6688        }
6689    }
6690
6691    void foregroundTokenDied(ForegroundToken token) {
6692        synchronized (ActivityManagerService.this) {
6693            synchronized (mPidsSelfLocked) {
6694                ForegroundToken cur
6695                    = mForegroundProcesses.get(token.pid);
6696                if (cur != token) {
6697                    return;
6698                }
6699                mForegroundProcesses.remove(token.pid);
6700                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6701                if (pr == null) {
6702                    return;
6703                }
6704                pr.forcingToForeground = null;
6705                updateProcessForegroundLocked(pr, false, false);
6706            }
6707            updateOomAdjLocked();
6708        }
6709    }
6710
6711    @Override
6712    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6713        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6714                "setProcessForeground()");
6715        synchronized(this) {
6716            boolean changed = false;
6717
6718            synchronized (mPidsSelfLocked) {
6719                ProcessRecord pr = mPidsSelfLocked.get(pid);
6720                if (pr == null && isForeground) {
6721                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6722                    return;
6723                }
6724                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6725                if (oldToken != null) {
6726                    oldToken.token.unlinkToDeath(oldToken, 0);
6727                    mForegroundProcesses.remove(pid);
6728                    if (pr != null) {
6729                        pr.forcingToForeground = null;
6730                    }
6731                    changed = true;
6732                }
6733                if (isForeground && token != null) {
6734                    ForegroundToken newToken = new ForegroundToken() {
6735                        @Override
6736                        public void binderDied() {
6737                            foregroundTokenDied(this);
6738                        }
6739                    };
6740                    newToken.pid = pid;
6741                    newToken.token = token;
6742                    try {
6743                        token.linkToDeath(newToken, 0);
6744                        mForegroundProcesses.put(pid, newToken);
6745                        pr.forcingToForeground = token;
6746                        changed = true;
6747                    } catch (RemoteException e) {
6748                        // If the process died while doing this, we will later
6749                        // do the cleanup with the process death link.
6750                    }
6751                }
6752            }
6753
6754            if (changed) {
6755                updateOomAdjLocked();
6756            }
6757        }
6758    }
6759
6760    // =========================================================
6761    // PERMISSIONS
6762    // =========================================================
6763
6764    static class PermissionController extends IPermissionController.Stub {
6765        ActivityManagerService mActivityManagerService;
6766        PermissionController(ActivityManagerService activityManagerService) {
6767            mActivityManagerService = activityManagerService;
6768        }
6769
6770        @Override
6771        public boolean checkPermission(String permission, int pid, int uid) {
6772            return mActivityManagerService.checkPermission(permission, pid,
6773                    uid) == PackageManager.PERMISSION_GRANTED;
6774        }
6775    }
6776
6777    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6778        @Override
6779        public int checkComponentPermission(String permission, int pid, int uid,
6780                int owningUid, boolean exported) {
6781            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6782                    owningUid, exported);
6783        }
6784
6785        @Override
6786        public Object getAMSLock() {
6787            return ActivityManagerService.this;
6788        }
6789    }
6790
6791    /**
6792     * This can be called with or without the global lock held.
6793     */
6794    int checkComponentPermission(String permission, int pid, int uid,
6795            int owningUid, boolean exported) {
6796        // We might be performing an operation on behalf of an indirect binder
6797        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6798        // client identity accordingly before proceeding.
6799        Identity tlsIdentity = sCallerIdentity.get();
6800        if (tlsIdentity != null) {
6801            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6802                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6803            uid = tlsIdentity.uid;
6804            pid = tlsIdentity.pid;
6805        }
6806
6807        if (pid == MY_PID) {
6808            return PackageManager.PERMISSION_GRANTED;
6809        }
6810
6811        return ActivityManager.checkComponentPermission(permission, uid,
6812                owningUid, exported);
6813    }
6814
6815    /**
6816     * As the only public entry point for permissions checking, this method
6817     * can enforce the semantic that requesting a check on a null global
6818     * permission is automatically denied.  (Internally a null permission
6819     * string is used when calling {@link #checkComponentPermission} in cases
6820     * when only uid-based security is needed.)
6821     *
6822     * This can be called with or without the global lock held.
6823     */
6824    @Override
6825    public int checkPermission(String permission, int pid, int uid) {
6826        if (permission == null) {
6827            return PackageManager.PERMISSION_DENIED;
6828        }
6829        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6830    }
6831
6832    /**
6833     * Binder IPC calls go through the public entry point.
6834     * This can be called with or without the global lock held.
6835     */
6836    int checkCallingPermission(String permission) {
6837        return checkPermission(permission,
6838                Binder.getCallingPid(),
6839                UserHandle.getAppId(Binder.getCallingUid()));
6840    }
6841
6842    /**
6843     * This can be called with or without the global lock held.
6844     */
6845    void enforceCallingPermission(String permission, String func) {
6846        if (checkCallingPermission(permission)
6847                == PackageManager.PERMISSION_GRANTED) {
6848            return;
6849        }
6850
6851        String msg = "Permission Denial: " + func + " from pid="
6852                + Binder.getCallingPid()
6853                + ", uid=" + Binder.getCallingUid()
6854                + " requires " + permission;
6855        Slog.w(TAG, msg);
6856        throw new SecurityException(msg);
6857    }
6858
6859    /**
6860     * Determine if UID is holding permissions required to access {@link Uri} in
6861     * the given {@link ProviderInfo}. Final permission checking is always done
6862     * in {@link ContentProvider}.
6863     */
6864    private final boolean checkHoldingPermissionsLocked(
6865            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6866        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6867                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6868        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6869            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6870                    != PERMISSION_GRANTED) {
6871                return false;
6872            }
6873        }
6874        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6875    }
6876
6877    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6878            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6879        if (pi.applicationInfo.uid == uid) {
6880            return true;
6881        } else if (!pi.exported) {
6882            return false;
6883        }
6884
6885        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6886        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6887        try {
6888            // check if target holds top-level <provider> permissions
6889            if (!readMet && pi.readPermission != null && considerUidPermissions
6890                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6891                readMet = true;
6892            }
6893            if (!writeMet && pi.writePermission != null && considerUidPermissions
6894                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6895                writeMet = true;
6896            }
6897
6898            // track if unprotected read/write is allowed; any denied
6899            // <path-permission> below removes this ability
6900            boolean allowDefaultRead = pi.readPermission == null;
6901            boolean allowDefaultWrite = pi.writePermission == null;
6902
6903            // check if target holds any <path-permission> that match uri
6904            final PathPermission[] pps = pi.pathPermissions;
6905            if (pps != null) {
6906                final String path = grantUri.uri.getPath();
6907                int i = pps.length;
6908                while (i > 0 && (!readMet || !writeMet)) {
6909                    i--;
6910                    PathPermission pp = pps[i];
6911                    if (pp.match(path)) {
6912                        if (!readMet) {
6913                            final String pprperm = pp.getReadPermission();
6914                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6915                                    + pprperm + " for " + pp.getPath()
6916                                    + ": match=" + pp.match(path)
6917                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6918                            if (pprperm != null) {
6919                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6920                                        == PERMISSION_GRANTED) {
6921                                    readMet = true;
6922                                } else {
6923                                    allowDefaultRead = false;
6924                                }
6925                            }
6926                        }
6927                        if (!writeMet) {
6928                            final String ppwperm = pp.getWritePermission();
6929                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6930                                    + ppwperm + " for " + pp.getPath()
6931                                    + ": match=" + pp.match(path)
6932                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6933                            if (ppwperm != null) {
6934                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6935                                        == PERMISSION_GRANTED) {
6936                                    writeMet = true;
6937                                } else {
6938                                    allowDefaultWrite = false;
6939                                }
6940                            }
6941                        }
6942                    }
6943                }
6944            }
6945
6946            // grant unprotected <provider> read/write, if not blocked by
6947            // <path-permission> above
6948            if (allowDefaultRead) readMet = true;
6949            if (allowDefaultWrite) writeMet = true;
6950
6951        } catch (RemoteException e) {
6952            return false;
6953        }
6954
6955        return readMet && writeMet;
6956    }
6957
6958    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6959        ProviderInfo pi = null;
6960        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6961        if (cpr != null) {
6962            pi = cpr.info;
6963        } else {
6964            try {
6965                pi = AppGlobals.getPackageManager().resolveContentProvider(
6966                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6967            } catch (RemoteException ex) {
6968            }
6969        }
6970        return pi;
6971    }
6972
6973    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6974        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6975        if (targetUris != null) {
6976            return targetUris.get(grantUri);
6977        }
6978        return null;
6979    }
6980
6981    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6982            String targetPkg, int targetUid, GrantUri grantUri) {
6983        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6984        if (targetUris == null) {
6985            targetUris = Maps.newArrayMap();
6986            mGrantedUriPermissions.put(targetUid, targetUris);
6987        }
6988
6989        UriPermission perm = targetUris.get(grantUri);
6990        if (perm == null) {
6991            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6992            targetUris.put(grantUri, perm);
6993        }
6994
6995        return perm;
6996    }
6997
6998    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6999            final int modeFlags) {
7000        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7001        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7002                : UriPermission.STRENGTH_OWNED;
7003
7004        // Root gets to do everything.
7005        if (uid == 0) {
7006            return true;
7007        }
7008
7009        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7010        if (perms == null) return false;
7011
7012        // First look for exact match
7013        final UriPermission exactPerm = perms.get(grantUri);
7014        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7015            return true;
7016        }
7017
7018        // No exact match, look for prefixes
7019        final int N = perms.size();
7020        for (int i = 0; i < N; i++) {
7021            final UriPermission perm = perms.valueAt(i);
7022            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7023                    && perm.getStrength(modeFlags) >= minStrength) {
7024                return true;
7025            }
7026        }
7027
7028        return false;
7029    }
7030
7031    /**
7032     * @param uri This uri must NOT contain an embedded userId.
7033     * @param userId The userId in which the uri is to be resolved.
7034     */
7035    @Override
7036    public int checkUriPermission(Uri uri, int pid, int uid,
7037            final int modeFlags, int userId) {
7038        enforceNotIsolatedCaller("checkUriPermission");
7039
7040        // Another redirected-binder-call permissions check as in
7041        // {@link checkComponentPermission}.
7042        Identity tlsIdentity = sCallerIdentity.get();
7043        if (tlsIdentity != null) {
7044            uid = tlsIdentity.uid;
7045            pid = tlsIdentity.pid;
7046        }
7047
7048        // Our own process gets to do everything.
7049        if (pid == MY_PID) {
7050            return PackageManager.PERMISSION_GRANTED;
7051        }
7052        synchronized (this) {
7053            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7054                    ? PackageManager.PERMISSION_GRANTED
7055                    : PackageManager.PERMISSION_DENIED;
7056        }
7057    }
7058
7059    /**
7060     * Check if the targetPkg can be granted permission to access uri by
7061     * the callingUid using the given modeFlags.  Throws a security exception
7062     * if callingUid is not allowed to do this.  Returns the uid of the target
7063     * if the URI permission grant should be performed; returns -1 if it is not
7064     * needed (for example targetPkg already has permission to access the URI).
7065     * If you already know the uid of the target, you can supply it in
7066     * lastTargetUid else set that to -1.
7067     */
7068    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7069            final int modeFlags, int lastTargetUid) {
7070        if (!Intent.isAccessUriMode(modeFlags)) {
7071            return -1;
7072        }
7073
7074        if (targetPkg != null) {
7075            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7076                    "Checking grant " + targetPkg + " permission to " + grantUri);
7077        }
7078
7079        final IPackageManager pm = AppGlobals.getPackageManager();
7080
7081        // If this is not a content: uri, we can't do anything with it.
7082        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7083            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7084                    "Can't grant URI permission for non-content URI: " + grantUri);
7085            return -1;
7086        }
7087
7088        final String authority = grantUri.uri.getAuthority();
7089        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7090        if (pi == null) {
7091            Slog.w(TAG, "No content provider found for permission check: " +
7092                    grantUri.uri.toSafeString());
7093            return -1;
7094        }
7095
7096        int targetUid = lastTargetUid;
7097        if (targetUid < 0 && targetPkg != null) {
7098            try {
7099                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7100                if (targetUid < 0) {
7101                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7102                            "Can't grant URI permission no uid for: " + targetPkg);
7103                    return -1;
7104                }
7105            } catch (RemoteException ex) {
7106                return -1;
7107            }
7108        }
7109
7110        if (targetUid >= 0) {
7111            // First...  does the target actually need this permission?
7112            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7113                // No need to grant the target this permission.
7114                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7115                        "Target " + targetPkg + " already has full permission to " + grantUri);
7116                return -1;
7117            }
7118        } else {
7119            // First...  there is no target package, so can anyone access it?
7120            boolean allowed = pi.exported;
7121            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7122                if (pi.readPermission != null) {
7123                    allowed = false;
7124                }
7125            }
7126            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7127                if (pi.writePermission != null) {
7128                    allowed = false;
7129                }
7130            }
7131            if (allowed) {
7132                return -1;
7133            }
7134        }
7135
7136        /* There is a special cross user grant if:
7137         * - The target is on another user.
7138         * - Apps on the current user can access the uri without any uid permissions.
7139         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7140         * grant uri permissions.
7141         */
7142        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7143                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7144                modeFlags, false /*without considering the uid permissions*/);
7145
7146        // Second...  is the provider allowing granting of URI permissions?
7147        if (!specialCrossUserGrant) {
7148            if (!pi.grantUriPermissions) {
7149                throw new SecurityException("Provider " + pi.packageName
7150                        + "/" + pi.name
7151                        + " does not allow granting of Uri permissions (uri "
7152                        + grantUri + ")");
7153            }
7154            if (pi.uriPermissionPatterns != null) {
7155                final int N = pi.uriPermissionPatterns.length;
7156                boolean allowed = false;
7157                for (int i=0; i<N; i++) {
7158                    if (pi.uriPermissionPatterns[i] != null
7159                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7160                        allowed = true;
7161                        break;
7162                    }
7163                }
7164                if (!allowed) {
7165                    throw new SecurityException("Provider " + pi.packageName
7166                            + "/" + pi.name
7167                            + " does not allow granting of permission to path of Uri "
7168                            + grantUri);
7169                }
7170            }
7171        }
7172
7173        // Third...  does the caller itself have permission to access
7174        // this uri?
7175        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7176            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7177                // Require they hold a strong enough Uri permission
7178                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7179                    throw new SecurityException("Uid " + callingUid
7180                            + " does not have permission to uri " + grantUri);
7181                }
7182            }
7183        }
7184        return targetUid;
7185    }
7186
7187    /**
7188     * @param uri This uri must NOT contain an embedded userId.
7189     * @param userId The userId in which the uri is to be resolved.
7190     */
7191    @Override
7192    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7193            final int modeFlags, int userId) {
7194        enforceNotIsolatedCaller("checkGrantUriPermission");
7195        synchronized(this) {
7196            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7197                    new GrantUri(userId, uri, false), modeFlags, -1);
7198        }
7199    }
7200
7201    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7202            final int modeFlags, UriPermissionOwner owner) {
7203        if (!Intent.isAccessUriMode(modeFlags)) {
7204            return;
7205        }
7206
7207        // So here we are: the caller has the assumed permission
7208        // to the uri, and the target doesn't.  Let's now give this to
7209        // the target.
7210
7211        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7212                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7213
7214        final String authority = grantUri.uri.getAuthority();
7215        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7216        if (pi == null) {
7217            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7218            return;
7219        }
7220
7221        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7222            grantUri.prefix = true;
7223        }
7224        final UriPermission perm = findOrCreateUriPermissionLocked(
7225                pi.packageName, targetPkg, targetUid, grantUri);
7226        perm.grantModes(modeFlags, owner);
7227    }
7228
7229    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7230            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7231        if (targetPkg == null) {
7232            throw new NullPointerException("targetPkg");
7233        }
7234        int targetUid;
7235        final IPackageManager pm = AppGlobals.getPackageManager();
7236        try {
7237            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7238        } catch (RemoteException ex) {
7239            return;
7240        }
7241
7242        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7243                targetUid);
7244        if (targetUid < 0) {
7245            return;
7246        }
7247
7248        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7249                owner);
7250    }
7251
7252    static class NeededUriGrants extends ArrayList<GrantUri> {
7253        final String targetPkg;
7254        final int targetUid;
7255        final int flags;
7256
7257        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7258            this.targetPkg = targetPkg;
7259            this.targetUid = targetUid;
7260            this.flags = flags;
7261        }
7262    }
7263
7264    /**
7265     * Like checkGrantUriPermissionLocked, but takes an Intent.
7266     */
7267    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7268            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7269        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7270                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7271                + " clip=" + (intent != null ? intent.getClipData() : null)
7272                + " from " + intent + "; flags=0x"
7273                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7274
7275        if (targetPkg == null) {
7276            throw new NullPointerException("targetPkg");
7277        }
7278
7279        if (intent == null) {
7280            return null;
7281        }
7282        Uri data = intent.getData();
7283        ClipData clip = intent.getClipData();
7284        if (data == null && clip == null) {
7285            return null;
7286        }
7287        // Default userId for uris in the intent (if they don't specify it themselves)
7288        int contentUserHint = intent.getContentUserHint();
7289        if (contentUserHint == UserHandle.USER_CURRENT) {
7290            contentUserHint = UserHandle.getUserId(callingUid);
7291        }
7292        final IPackageManager pm = AppGlobals.getPackageManager();
7293        int targetUid;
7294        if (needed != null) {
7295            targetUid = needed.targetUid;
7296        } else {
7297            try {
7298                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7299            } catch (RemoteException ex) {
7300                return null;
7301            }
7302            if (targetUid < 0) {
7303                if (DEBUG_URI_PERMISSION) {
7304                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7305                            + " on user " + targetUserId);
7306                }
7307                return null;
7308            }
7309        }
7310        if (data != null) {
7311            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7312            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7313                    targetUid);
7314            if (targetUid > 0) {
7315                if (needed == null) {
7316                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7317                }
7318                needed.add(grantUri);
7319            }
7320        }
7321        if (clip != null) {
7322            for (int i=0; i<clip.getItemCount(); i++) {
7323                Uri uri = clip.getItemAt(i).getUri();
7324                if (uri != null) {
7325                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7326                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7327                            targetUid);
7328                    if (targetUid > 0) {
7329                        if (needed == null) {
7330                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7331                        }
7332                        needed.add(grantUri);
7333                    }
7334                } else {
7335                    Intent clipIntent = clip.getItemAt(i).getIntent();
7336                    if (clipIntent != null) {
7337                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7338                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7339                        if (newNeeded != null) {
7340                            needed = newNeeded;
7341                        }
7342                    }
7343                }
7344            }
7345        }
7346
7347        return needed;
7348    }
7349
7350    /**
7351     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7352     */
7353    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7354            UriPermissionOwner owner) {
7355        if (needed != null) {
7356            for (int i=0; i<needed.size(); i++) {
7357                GrantUri grantUri = needed.get(i);
7358                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7359                        grantUri, needed.flags, owner);
7360            }
7361        }
7362    }
7363
7364    void grantUriPermissionFromIntentLocked(int callingUid,
7365            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7366        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7367                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7368        if (needed == null) {
7369            return;
7370        }
7371
7372        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7373    }
7374
7375    /**
7376     * @param uri This uri must NOT contain an embedded userId.
7377     * @param userId The userId in which the uri is to be resolved.
7378     */
7379    @Override
7380    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7381            final int modeFlags, int userId) {
7382        enforceNotIsolatedCaller("grantUriPermission");
7383        GrantUri grantUri = new GrantUri(userId, uri, false);
7384        synchronized(this) {
7385            final ProcessRecord r = getRecordForAppLocked(caller);
7386            if (r == null) {
7387                throw new SecurityException("Unable to find app for caller "
7388                        + caller
7389                        + " when granting permission to uri " + grantUri);
7390            }
7391            if (targetPkg == null) {
7392                throw new IllegalArgumentException("null target");
7393            }
7394            if (grantUri == null) {
7395                throw new IllegalArgumentException("null uri");
7396            }
7397
7398            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7399                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7400                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7401                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7402
7403            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7404                    UserHandle.getUserId(r.uid));
7405        }
7406    }
7407
7408    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7409        if (perm.modeFlags == 0) {
7410            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7411                    perm.targetUid);
7412            if (perms != null) {
7413                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7414                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7415
7416                perms.remove(perm.uri);
7417                if (perms.isEmpty()) {
7418                    mGrantedUriPermissions.remove(perm.targetUid);
7419                }
7420            }
7421        }
7422    }
7423
7424    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7425        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7426
7427        final IPackageManager pm = AppGlobals.getPackageManager();
7428        final String authority = grantUri.uri.getAuthority();
7429        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7430        if (pi == null) {
7431            Slog.w(TAG, "No content provider found for permission revoke: "
7432                    + grantUri.toSafeString());
7433            return;
7434        }
7435
7436        // Does the caller have this permission on the URI?
7437        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7438            // Right now, if you are not the original owner of the permission,
7439            // you are not allowed to revoke it.
7440            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7441                throw new SecurityException("Uid " + callingUid
7442                        + " does not have permission to uri " + grantUri);
7443            //}
7444        }
7445
7446        boolean persistChanged = false;
7447
7448        // Go through all of the permissions and remove any that match.
7449        int N = mGrantedUriPermissions.size();
7450        for (int i = 0; i < N; i++) {
7451            final int targetUid = mGrantedUriPermissions.keyAt(i);
7452            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7453
7454            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7455                final UriPermission perm = it.next();
7456                if (perm.uri.sourceUserId == grantUri.sourceUserId
7457                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7458                    if (DEBUG_URI_PERMISSION)
7459                        Slog.v(TAG,
7460                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7461                    persistChanged |= perm.revokeModes(
7462                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7463                    if (perm.modeFlags == 0) {
7464                        it.remove();
7465                    }
7466                }
7467            }
7468
7469            if (perms.isEmpty()) {
7470                mGrantedUriPermissions.remove(targetUid);
7471                N--;
7472                i--;
7473            }
7474        }
7475
7476        if (persistChanged) {
7477            schedulePersistUriGrants();
7478        }
7479    }
7480
7481    /**
7482     * @param uri This uri must NOT contain an embedded userId.
7483     * @param userId The userId in which the uri is to be resolved.
7484     */
7485    @Override
7486    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7487            int userId) {
7488        enforceNotIsolatedCaller("revokeUriPermission");
7489        synchronized(this) {
7490            final ProcessRecord r = getRecordForAppLocked(caller);
7491            if (r == null) {
7492                throw new SecurityException("Unable to find app for caller "
7493                        + caller
7494                        + " when revoking permission to uri " + uri);
7495            }
7496            if (uri == null) {
7497                Slog.w(TAG, "revokeUriPermission: null uri");
7498                return;
7499            }
7500
7501            if (!Intent.isAccessUriMode(modeFlags)) {
7502                return;
7503            }
7504
7505            final IPackageManager pm = AppGlobals.getPackageManager();
7506            final String authority = uri.getAuthority();
7507            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7508            if (pi == null) {
7509                Slog.w(TAG, "No content provider found for permission revoke: "
7510                        + uri.toSafeString());
7511                return;
7512            }
7513
7514            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7515        }
7516    }
7517
7518    /**
7519     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7520     * given package.
7521     *
7522     * @param packageName Package name to match, or {@code null} to apply to all
7523     *            packages.
7524     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7525     *            to all users.
7526     * @param persistable If persistable grants should be removed.
7527     */
7528    private void removeUriPermissionsForPackageLocked(
7529            String packageName, int userHandle, boolean persistable) {
7530        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7531            throw new IllegalArgumentException("Must narrow by either package or user");
7532        }
7533
7534        boolean persistChanged = false;
7535
7536        int N = mGrantedUriPermissions.size();
7537        for (int i = 0; i < N; i++) {
7538            final int targetUid = mGrantedUriPermissions.keyAt(i);
7539            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7540
7541            // Only inspect grants matching user
7542            if (userHandle == UserHandle.USER_ALL
7543                    || userHandle == UserHandle.getUserId(targetUid)) {
7544                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7545                    final UriPermission perm = it.next();
7546
7547                    // Only inspect grants matching package
7548                    if (packageName == null || perm.sourcePkg.equals(packageName)
7549                            || perm.targetPkg.equals(packageName)) {
7550                        persistChanged |= perm.revokeModes(
7551                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7552
7553                        // Only remove when no modes remain; any persisted grants
7554                        // will keep this alive.
7555                        if (perm.modeFlags == 0) {
7556                            it.remove();
7557                        }
7558                    }
7559                }
7560
7561                if (perms.isEmpty()) {
7562                    mGrantedUriPermissions.remove(targetUid);
7563                    N--;
7564                    i--;
7565                }
7566            }
7567        }
7568
7569        if (persistChanged) {
7570            schedulePersistUriGrants();
7571        }
7572    }
7573
7574    @Override
7575    public IBinder newUriPermissionOwner(String name) {
7576        enforceNotIsolatedCaller("newUriPermissionOwner");
7577        synchronized(this) {
7578            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7579            return owner.getExternalTokenLocked();
7580        }
7581    }
7582
7583    /**
7584     * @param uri This uri must NOT contain an embedded userId.
7585     * @param sourceUserId The userId in which the uri is to be resolved.
7586     * @param targetUserId The userId of the app that receives the grant.
7587     */
7588    @Override
7589    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7590            final int modeFlags, int sourceUserId, int targetUserId) {
7591        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7592                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7593        synchronized(this) {
7594            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7595            if (owner == null) {
7596                throw new IllegalArgumentException("Unknown owner: " + token);
7597            }
7598            if (fromUid != Binder.getCallingUid()) {
7599                if (Binder.getCallingUid() != Process.myUid()) {
7600                    // Only system code can grant URI permissions on behalf
7601                    // of other users.
7602                    throw new SecurityException("nice try");
7603                }
7604            }
7605            if (targetPkg == null) {
7606                throw new IllegalArgumentException("null target");
7607            }
7608            if (uri == null) {
7609                throw new IllegalArgumentException("null uri");
7610            }
7611
7612            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7613                    modeFlags, owner, targetUserId);
7614        }
7615    }
7616
7617    /**
7618     * @param uri This uri must NOT contain an embedded userId.
7619     * @param userId The userId in which the uri is to be resolved.
7620     */
7621    @Override
7622    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7623        synchronized(this) {
7624            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7625            if (owner == null) {
7626                throw new IllegalArgumentException("Unknown owner: " + token);
7627            }
7628
7629            if (uri == null) {
7630                owner.removeUriPermissionsLocked(mode);
7631            } else {
7632                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7633            }
7634        }
7635    }
7636
7637    private void schedulePersistUriGrants() {
7638        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7639            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7640                    10 * DateUtils.SECOND_IN_MILLIS);
7641        }
7642    }
7643
7644    private void writeGrantedUriPermissions() {
7645        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7646
7647        // Snapshot permissions so we can persist without lock
7648        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7649        synchronized (this) {
7650            final int size = mGrantedUriPermissions.size();
7651            for (int i = 0; i < size; i++) {
7652                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7653                for (UriPermission perm : perms.values()) {
7654                    if (perm.persistedModeFlags != 0) {
7655                        persist.add(perm.snapshot());
7656                    }
7657                }
7658            }
7659        }
7660
7661        FileOutputStream fos = null;
7662        try {
7663            fos = mGrantFile.startWrite();
7664
7665            XmlSerializer out = new FastXmlSerializer();
7666            out.setOutput(fos, "utf-8");
7667            out.startDocument(null, true);
7668            out.startTag(null, TAG_URI_GRANTS);
7669            for (UriPermission.Snapshot perm : persist) {
7670                out.startTag(null, TAG_URI_GRANT);
7671                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7672                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7673                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7674                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7675                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7676                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7677                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7678                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7679                out.endTag(null, TAG_URI_GRANT);
7680            }
7681            out.endTag(null, TAG_URI_GRANTS);
7682            out.endDocument();
7683
7684            mGrantFile.finishWrite(fos);
7685        } catch (IOException e) {
7686            if (fos != null) {
7687                mGrantFile.failWrite(fos);
7688            }
7689        }
7690    }
7691
7692    private void readGrantedUriPermissionsLocked() {
7693        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7694
7695        final long now = System.currentTimeMillis();
7696
7697        FileInputStream fis = null;
7698        try {
7699            fis = mGrantFile.openRead();
7700            final XmlPullParser in = Xml.newPullParser();
7701            in.setInput(fis, null);
7702
7703            int type;
7704            while ((type = in.next()) != END_DOCUMENT) {
7705                final String tag = in.getName();
7706                if (type == START_TAG) {
7707                    if (TAG_URI_GRANT.equals(tag)) {
7708                        final int sourceUserId;
7709                        final int targetUserId;
7710                        final int userHandle = readIntAttribute(in,
7711                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7712                        if (userHandle != UserHandle.USER_NULL) {
7713                            // For backwards compatibility.
7714                            sourceUserId = userHandle;
7715                            targetUserId = userHandle;
7716                        } else {
7717                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7718                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7719                        }
7720                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7721                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7722                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7723                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7724                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7725                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7726
7727                        // Sanity check that provider still belongs to source package
7728                        final ProviderInfo pi = getProviderInfoLocked(
7729                                uri.getAuthority(), sourceUserId);
7730                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7731                            int targetUid = -1;
7732                            try {
7733                                targetUid = AppGlobals.getPackageManager()
7734                                        .getPackageUid(targetPkg, targetUserId);
7735                            } catch (RemoteException e) {
7736                            }
7737                            if (targetUid != -1) {
7738                                final UriPermission perm = findOrCreateUriPermissionLocked(
7739                                        sourcePkg, targetPkg, targetUid,
7740                                        new GrantUri(sourceUserId, uri, prefix));
7741                                perm.initPersistedModes(modeFlags, createdTime);
7742                            }
7743                        } else {
7744                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7745                                    + " but instead found " + pi);
7746                        }
7747                    }
7748                }
7749            }
7750        } catch (FileNotFoundException e) {
7751            // Missing grants is okay
7752        } catch (IOException e) {
7753            Log.wtf(TAG, "Failed reading Uri grants", e);
7754        } catch (XmlPullParserException e) {
7755            Log.wtf(TAG, "Failed reading Uri grants", e);
7756        } finally {
7757            IoUtils.closeQuietly(fis);
7758        }
7759    }
7760
7761    /**
7762     * @param uri This uri must NOT contain an embedded userId.
7763     * @param userId The userId in which the uri is to be resolved.
7764     */
7765    @Override
7766    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7767        enforceNotIsolatedCaller("takePersistableUriPermission");
7768
7769        Preconditions.checkFlagsArgument(modeFlags,
7770                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7771
7772        synchronized (this) {
7773            final int callingUid = Binder.getCallingUid();
7774            boolean persistChanged = false;
7775            GrantUri grantUri = new GrantUri(userId, uri, false);
7776
7777            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7778                    new GrantUri(userId, uri, false));
7779            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7780                    new GrantUri(userId, uri, true));
7781
7782            final boolean exactValid = (exactPerm != null)
7783                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7784            final boolean prefixValid = (prefixPerm != null)
7785                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7786
7787            if (!(exactValid || prefixValid)) {
7788                throw new SecurityException("No persistable permission grants found for UID "
7789                        + callingUid + " and Uri " + grantUri.toSafeString());
7790            }
7791
7792            if (exactValid) {
7793                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7794            }
7795            if (prefixValid) {
7796                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7797            }
7798
7799            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7800
7801            if (persistChanged) {
7802                schedulePersistUriGrants();
7803            }
7804        }
7805    }
7806
7807    /**
7808     * @param uri This uri must NOT contain an embedded userId.
7809     * @param userId The userId in which the uri is to be resolved.
7810     */
7811    @Override
7812    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7813        enforceNotIsolatedCaller("releasePersistableUriPermission");
7814
7815        Preconditions.checkFlagsArgument(modeFlags,
7816                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7817
7818        synchronized (this) {
7819            final int callingUid = Binder.getCallingUid();
7820            boolean persistChanged = false;
7821
7822            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7823                    new GrantUri(userId, uri, false));
7824            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7825                    new GrantUri(userId, uri, true));
7826            if (exactPerm == null && prefixPerm == null) {
7827                throw new SecurityException("No permission grants found for UID " + callingUid
7828                        + " and Uri " + uri.toSafeString());
7829            }
7830
7831            if (exactPerm != null) {
7832                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7833                removeUriPermissionIfNeededLocked(exactPerm);
7834            }
7835            if (prefixPerm != null) {
7836                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7837                removeUriPermissionIfNeededLocked(prefixPerm);
7838            }
7839
7840            if (persistChanged) {
7841                schedulePersistUriGrants();
7842            }
7843        }
7844    }
7845
7846    /**
7847     * Prune any older {@link UriPermission} for the given UID until outstanding
7848     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7849     *
7850     * @return if any mutations occured that require persisting.
7851     */
7852    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7853        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7854        if (perms == null) return false;
7855        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7856
7857        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7858        for (UriPermission perm : perms.values()) {
7859            if (perm.persistedModeFlags != 0) {
7860                persisted.add(perm);
7861            }
7862        }
7863
7864        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7865        if (trimCount <= 0) return false;
7866
7867        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7868        for (int i = 0; i < trimCount; i++) {
7869            final UriPermission perm = persisted.get(i);
7870
7871            if (DEBUG_URI_PERMISSION) {
7872                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7873            }
7874
7875            perm.releasePersistableModes(~0);
7876            removeUriPermissionIfNeededLocked(perm);
7877        }
7878
7879        return true;
7880    }
7881
7882    @Override
7883    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7884            String packageName, boolean incoming) {
7885        enforceNotIsolatedCaller("getPersistedUriPermissions");
7886        Preconditions.checkNotNull(packageName, "packageName");
7887
7888        final int callingUid = Binder.getCallingUid();
7889        final IPackageManager pm = AppGlobals.getPackageManager();
7890        try {
7891            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7892            if (packageUid != callingUid) {
7893                throw new SecurityException(
7894                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7895            }
7896        } catch (RemoteException e) {
7897            throw new SecurityException("Failed to verify package name ownership");
7898        }
7899
7900        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7901        synchronized (this) {
7902            if (incoming) {
7903                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7904                        callingUid);
7905                if (perms == null) {
7906                    Slog.w(TAG, "No permission grants found for " + packageName);
7907                } else {
7908                    for (UriPermission perm : perms.values()) {
7909                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7910                            result.add(perm.buildPersistedPublicApiObject());
7911                        }
7912                    }
7913                }
7914            } else {
7915                final int size = mGrantedUriPermissions.size();
7916                for (int i = 0; i < size; i++) {
7917                    final ArrayMap<GrantUri, UriPermission> perms =
7918                            mGrantedUriPermissions.valueAt(i);
7919                    for (UriPermission perm : perms.values()) {
7920                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7921                            result.add(perm.buildPersistedPublicApiObject());
7922                        }
7923                    }
7924                }
7925            }
7926        }
7927        return new ParceledListSlice<android.content.UriPermission>(result);
7928    }
7929
7930    @Override
7931    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7932        synchronized (this) {
7933            ProcessRecord app =
7934                who != null ? getRecordForAppLocked(who) : null;
7935            if (app == null) return;
7936
7937            Message msg = Message.obtain();
7938            msg.what = WAIT_FOR_DEBUGGER_MSG;
7939            msg.obj = app;
7940            msg.arg1 = waiting ? 1 : 0;
7941            mHandler.sendMessage(msg);
7942        }
7943    }
7944
7945    @Override
7946    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7947        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7948        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7949        outInfo.availMem = Process.getFreeMemory();
7950        outInfo.totalMem = Process.getTotalMemory();
7951        outInfo.threshold = homeAppMem;
7952        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7953        outInfo.hiddenAppThreshold = cachedAppMem;
7954        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7955                ProcessList.SERVICE_ADJ);
7956        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7957                ProcessList.VISIBLE_APP_ADJ);
7958        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7959                ProcessList.FOREGROUND_APP_ADJ);
7960    }
7961
7962    // =========================================================
7963    // TASK MANAGEMENT
7964    // =========================================================
7965
7966    @Override
7967    public List<IAppTask> getAppTasks(String callingPackage) {
7968        int callingUid = Binder.getCallingUid();
7969        long ident = Binder.clearCallingIdentity();
7970
7971        synchronized(this) {
7972            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7973            try {
7974                if (localLOGV) Slog.v(TAG, "getAppTasks");
7975
7976                final int N = mRecentTasks.size();
7977                for (int i = 0; i < N; i++) {
7978                    TaskRecord tr = mRecentTasks.get(i);
7979                    // Skip tasks that do not match the caller.  We don't need to verify
7980                    // callingPackage, because we are also limiting to callingUid and know
7981                    // that will limit to the correct security sandbox.
7982                    if (tr.effectiveUid != callingUid) {
7983                        continue;
7984                    }
7985                    Intent intent = tr.getBaseIntent();
7986                    if (intent == null ||
7987                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7988                        continue;
7989                    }
7990                    ActivityManager.RecentTaskInfo taskInfo =
7991                            createRecentTaskInfoFromTaskRecord(tr);
7992                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7993                    list.add(taskImpl);
7994                }
7995            } finally {
7996                Binder.restoreCallingIdentity(ident);
7997            }
7998            return list;
7999        }
8000    }
8001
8002    @Override
8003    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8004        final int callingUid = Binder.getCallingUid();
8005        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8006
8007        synchronized(this) {
8008            if (localLOGV) Slog.v(
8009                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8010
8011            final boolean allowed = checkCallingPermission(
8012                    android.Manifest.permission.GET_TASKS)
8013                    == PackageManager.PERMISSION_GRANTED;
8014            if (!allowed) {
8015                Slog.w(TAG, "getTasks: caller " + callingUid
8016                        + " does not hold GET_TASKS; limiting output");
8017            }
8018
8019            // TODO: Improve with MRU list from all ActivityStacks.
8020            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8021        }
8022
8023        return list;
8024    }
8025
8026    TaskRecord getMostRecentTask() {
8027        return mRecentTasks.get(0);
8028    }
8029
8030    /**
8031     * Creates a new RecentTaskInfo from a TaskRecord.
8032     */
8033    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8034        // Update the task description to reflect any changes in the task stack
8035        tr.updateTaskDescription();
8036
8037        // Compose the recent task info
8038        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8039        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8040        rti.persistentId = tr.taskId;
8041        rti.baseIntent = new Intent(tr.getBaseIntent());
8042        rti.origActivity = tr.origActivity;
8043        rti.description = tr.lastDescription;
8044        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8045        rti.userId = tr.userId;
8046        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8047        rti.firstActiveTime = tr.firstActiveTime;
8048        rti.lastActiveTime = tr.lastActiveTime;
8049        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8050        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8051        return rti;
8052    }
8053
8054    @Override
8055    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8056        final int callingUid = Binder.getCallingUid();
8057        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8058                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8059
8060        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8061        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8062        synchronized (this) {
8063            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8064                    == PackageManager.PERMISSION_GRANTED;
8065            if (!allowed) {
8066                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8067                        + " does not hold GET_TASKS; limiting output");
8068            }
8069            final boolean detailed = checkCallingPermission(
8070                    android.Manifest.permission.GET_DETAILED_TASKS)
8071                    == PackageManager.PERMISSION_GRANTED;
8072
8073            final int N = mRecentTasks.size();
8074            ArrayList<ActivityManager.RecentTaskInfo> res
8075                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8076                            maxNum < N ? maxNum : N);
8077
8078            final Set<Integer> includedUsers;
8079            if (includeProfiles) {
8080                includedUsers = getProfileIdsLocked(userId);
8081            } else {
8082                includedUsers = new HashSet<Integer>();
8083            }
8084            includedUsers.add(Integer.valueOf(userId));
8085
8086            for (int i=0; i<N && maxNum > 0; i++) {
8087                TaskRecord tr = mRecentTasks.get(i);
8088                // Only add calling user or related users recent tasks
8089                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8090                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8091                    continue;
8092                }
8093
8094                // Return the entry if desired by the caller.  We always return
8095                // the first entry, because callers always expect this to be the
8096                // foreground app.  We may filter others if the caller has
8097                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8098                // we should exclude the entry.
8099
8100                if (i == 0
8101                        || withExcluded
8102                        || (tr.intent == null)
8103                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8104                                == 0)) {
8105                    if (!allowed) {
8106                        // If the caller doesn't have the GET_TASKS permission, then only
8107                        // allow them to see a small subset of tasks -- their own and home.
8108                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8109                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8110                            continue;
8111                        }
8112                    }
8113                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8114                        if (tr.stack != null && tr.stack.isHomeStack()) {
8115                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8116                            continue;
8117                        }
8118                    }
8119                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8120                        // Don't include auto remove tasks that are finished or finishing.
8121                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8122                                + tr);
8123                        continue;
8124                    }
8125                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8126                            && !tr.isAvailable) {
8127                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8128                        continue;
8129                    }
8130
8131                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8132                    if (!detailed) {
8133                        rti.baseIntent.replaceExtras((Bundle)null);
8134                    }
8135
8136                    res.add(rti);
8137                    maxNum--;
8138                }
8139            }
8140            return res;
8141        }
8142    }
8143
8144    private TaskRecord recentTaskForIdLocked(int id) {
8145        final int N = mRecentTasks.size();
8146            for (int i=0; i<N; i++) {
8147                TaskRecord tr = mRecentTasks.get(i);
8148                if (tr.taskId == id) {
8149                    return tr;
8150                }
8151            }
8152            return null;
8153    }
8154
8155    @Override
8156    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8157        synchronized (this) {
8158            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8159                    "getTaskThumbnail()");
8160            TaskRecord tr = recentTaskForIdLocked(id);
8161            if (tr != null) {
8162                return tr.getTaskThumbnailLocked();
8163            }
8164        }
8165        return null;
8166    }
8167
8168    @Override
8169    public int addAppTask(IBinder activityToken, Intent intent,
8170            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8171        final int callingUid = Binder.getCallingUid();
8172        final long callingIdent = Binder.clearCallingIdentity();
8173
8174        try {
8175            synchronized (this) {
8176                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8177                if (r == null) {
8178                    throw new IllegalArgumentException("Activity does not exist; token="
8179                            + activityToken);
8180                }
8181                ComponentName comp = intent.getComponent();
8182                if (comp == null) {
8183                    throw new IllegalArgumentException("Intent " + intent
8184                            + " must specify explicit component");
8185                }
8186                if (thumbnail.getWidth() != mThumbnailWidth
8187                        || thumbnail.getHeight() != mThumbnailHeight) {
8188                    throw new IllegalArgumentException("Bad thumbnail size: got "
8189                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8190                            + mThumbnailWidth + "x" + mThumbnailHeight);
8191                }
8192                if (intent.getSelector() != null) {
8193                    intent.setSelector(null);
8194                }
8195                if (intent.getSourceBounds() != null) {
8196                    intent.setSourceBounds(null);
8197                }
8198                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8199                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8200                        // The caller has added this as an auto-remove task...  that makes no
8201                        // sense, so turn off auto-remove.
8202                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8203                    }
8204                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8205                    // Must be a new task.
8206                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8207                }
8208                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8209                    mLastAddedTaskActivity = null;
8210                }
8211                ActivityInfo ainfo = mLastAddedTaskActivity;
8212                if (ainfo == null) {
8213                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8214                            comp, 0, UserHandle.getUserId(callingUid));
8215                    if (ainfo.applicationInfo.uid != callingUid) {
8216                        throw new SecurityException(
8217                                "Can't add task for another application: target uid="
8218                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8219                    }
8220                }
8221
8222                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8223                        intent, description);
8224
8225                int trimIdx = trimRecentsForTask(task, false);
8226                if (trimIdx >= 0) {
8227                    // If this would have caused a trim, then we'll abort because that
8228                    // means it would be added at the end of the list but then just removed.
8229                    return -1;
8230                }
8231
8232                final int N = mRecentTasks.size();
8233                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8234                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8235                    tr.removedFromRecents(mTaskPersister);
8236                }
8237
8238                task.inRecents = true;
8239                mRecentTasks.add(task);
8240                r.task.stack.addTask(task, false, false);
8241
8242                task.setLastThumbnail(thumbnail);
8243                task.freeLastThumbnail();
8244
8245                return task.taskId;
8246            }
8247        } finally {
8248            Binder.restoreCallingIdentity(callingIdent);
8249        }
8250    }
8251
8252    @Override
8253    public Point getAppTaskThumbnailSize() {
8254        synchronized (this) {
8255            return new Point(mThumbnailWidth,  mThumbnailHeight);
8256        }
8257    }
8258
8259    @Override
8260    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8261        synchronized (this) {
8262            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8263            if (r != null) {
8264                r.taskDescription = td;
8265                r.task.updateTaskDescription();
8266            }
8267        }
8268    }
8269
8270    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8271        mRecentTasks.remove(tr);
8272        tr.removedFromRecents(mTaskPersister);
8273        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8274        Intent baseIntent = new Intent(
8275                tr.intent != null ? tr.intent : tr.affinityIntent);
8276        ComponentName component = baseIntent.getComponent();
8277        if (component == null) {
8278            Slog.w(TAG, "Now component for base intent of task: " + tr);
8279            return;
8280        }
8281
8282        // Find any running services associated with this app.
8283        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8284
8285        if (killProcesses) {
8286            // Find any running processes associated with this app.
8287            final String pkg = component.getPackageName();
8288            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8289            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8290            for (int i=0; i<pmap.size(); i++) {
8291                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8292                for (int j=0; j<uids.size(); j++) {
8293                    ProcessRecord proc = uids.valueAt(j);
8294                    if (proc.userId != tr.userId) {
8295                        continue;
8296                    }
8297                    if (!proc.pkgList.containsKey(pkg)) {
8298                        continue;
8299                    }
8300                    procs.add(proc);
8301                }
8302            }
8303
8304            // Kill the running processes.
8305            for (int i=0; i<procs.size(); i++) {
8306                ProcessRecord pr = procs.get(i);
8307                if (pr == mHomeProcess) {
8308                    // Don't kill the home process along with tasks from the same package.
8309                    continue;
8310                }
8311                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8312                    pr.kill("remove task", true);
8313                } else {
8314                    pr.waitingToKill = "remove task";
8315                }
8316            }
8317        }
8318    }
8319
8320    /**
8321     * Removes the task with the specified task id.
8322     *
8323     * @param taskId Identifier of the task to be removed.
8324     * @param flags Additional operational flags.  May be 0 or
8325     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8326     * @return Returns true if the given task was found and removed.
8327     */
8328    private boolean removeTaskByIdLocked(int taskId, int flags) {
8329        TaskRecord tr = recentTaskForIdLocked(taskId);
8330        if (tr != null) {
8331            tr.removeTaskActivitiesLocked();
8332            cleanUpRemovedTaskLocked(tr, flags);
8333            if (tr.isPersistable) {
8334                notifyTaskPersisterLocked(null, true);
8335            }
8336            return true;
8337        }
8338        return false;
8339    }
8340
8341    @Override
8342    public boolean removeTask(int taskId, int flags) {
8343        synchronized (this) {
8344            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8345                    "removeTask()");
8346            long ident = Binder.clearCallingIdentity();
8347            try {
8348                return removeTaskByIdLocked(taskId, flags);
8349            } finally {
8350                Binder.restoreCallingIdentity(ident);
8351            }
8352        }
8353    }
8354
8355    /**
8356     * TODO: Add mController hook
8357     */
8358    @Override
8359    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8360        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8361                "moveTaskToFront()");
8362
8363        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8364        synchronized(this) {
8365            moveTaskToFrontLocked(taskId, flags, options);
8366        }
8367    }
8368
8369    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8370        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8371                Binder.getCallingUid(), "Task to front")) {
8372            ActivityOptions.abort(options);
8373            return;
8374        }
8375        final long origId = Binder.clearCallingIdentity();
8376        try {
8377            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8378            if (task == null) {
8379                return;
8380            }
8381            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8382                mStackSupervisor.showLockTaskToast();
8383                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8384                return;
8385            }
8386            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8387            if (prev != null && prev.isRecentsActivity()) {
8388                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8389            }
8390            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8391        } finally {
8392            Binder.restoreCallingIdentity(origId);
8393        }
8394        ActivityOptions.abort(options);
8395    }
8396
8397    @Override
8398    public void moveTaskToBack(int taskId) {
8399        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8400                "moveTaskToBack()");
8401
8402        synchronized(this) {
8403            TaskRecord tr = recentTaskForIdLocked(taskId);
8404            if (tr != null) {
8405                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8406                ActivityStack stack = tr.stack;
8407                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8408                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8409                            Binder.getCallingUid(), "Task to back")) {
8410                        return;
8411                    }
8412                }
8413                final long origId = Binder.clearCallingIdentity();
8414                try {
8415                    stack.moveTaskToBackLocked(taskId, null);
8416                } finally {
8417                    Binder.restoreCallingIdentity(origId);
8418                }
8419            }
8420        }
8421    }
8422
8423    /**
8424     * Moves an activity, and all of the other activities within the same task, to the bottom
8425     * of the history stack.  The activity's order within the task is unchanged.
8426     *
8427     * @param token A reference to the activity we wish to move
8428     * @param nonRoot If false then this only works if the activity is the root
8429     *                of a task; if true it will work for any activity in a task.
8430     * @return Returns true if the move completed, false if not.
8431     */
8432    @Override
8433    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8434        enforceNotIsolatedCaller("moveActivityTaskToBack");
8435        synchronized(this) {
8436            final long origId = Binder.clearCallingIdentity();
8437            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8438            if (taskId >= 0) {
8439                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8440            }
8441            Binder.restoreCallingIdentity(origId);
8442        }
8443        return false;
8444    }
8445
8446    @Override
8447    public void moveTaskBackwards(int task) {
8448        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8449                "moveTaskBackwards()");
8450
8451        synchronized(this) {
8452            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8453                    Binder.getCallingUid(), "Task backwards")) {
8454                return;
8455            }
8456            final long origId = Binder.clearCallingIdentity();
8457            moveTaskBackwardsLocked(task);
8458            Binder.restoreCallingIdentity(origId);
8459        }
8460    }
8461
8462    private final void moveTaskBackwardsLocked(int task) {
8463        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8464    }
8465
8466    @Override
8467    public IBinder getHomeActivityToken() throws RemoteException {
8468        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8469                "getHomeActivityToken()");
8470        synchronized (this) {
8471            return mStackSupervisor.getHomeActivityToken();
8472        }
8473    }
8474
8475    @Override
8476    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8477            IActivityContainerCallback callback) throws RemoteException {
8478        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8479                "createActivityContainer()");
8480        synchronized (this) {
8481            if (parentActivityToken == null) {
8482                throw new IllegalArgumentException("parent token must not be null");
8483            }
8484            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8485            if (r == null) {
8486                return null;
8487            }
8488            if (callback == null) {
8489                throw new IllegalArgumentException("callback must not be null");
8490            }
8491            return mStackSupervisor.createActivityContainer(r, callback);
8492        }
8493    }
8494
8495    @Override
8496    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8497        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8498                "deleteActivityContainer()");
8499        synchronized (this) {
8500            mStackSupervisor.deleteActivityContainer(container);
8501        }
8502    }
8503
8504    @Override
8505    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8506            throws RemoteException {
8507        synchronized (this) {
8508            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8509            if (stack != null) {
8510                return stack.mActivityContainer;
8511            }
8512            return null;
8513        }
8514    }
8515
8516    @Override
8517    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8518        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8519                "moveTaskToStack()");
8520        if (stackId == HOME_STACK_ID) {
8521            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8522                    new RuntimeException("here").fillInStackTrace());
8523        }
8524        synchronized (this) {
8525            long ident = Binder.clearCallingIdentity();
8526            try {
8527                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8528                        + stackId + " toTop=" + toTop);
8529                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8530            } finally {
8531                Binder.restoreCallingIdentity(ident);
8532            }
8533        }
8534    }
8535
8536    @Override
8537    public void resizeStack(int stackBoxId, Rect bounds) {
8538        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8539                "resizeStackBox()");
8540        long ident = Binder.clearCallingIdentity();
8541        try {
8542            mWindowManager.resizeStack(stackBoxId, bounds);
8543        } finally {
8544            Binder.restoreCallingIdentity(ident);
8545        }
8546    }
8547
8548    @Override
8549    public List<StackInfo> getAllStackInfos() {
8550        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8551                "getAllStackInfos()");
8552        long ident = Binder.clearCallingIdentity();
8553        try {
8554            synchronized (this) {
8555                return mStackSupervisor.getAllStackInfosLocked();
8556            }
8557        } finally {
8558            Binder.restoreCallingIdentity(ident);
8559        }
8560    }
8561
8562    @Override
8563    public StackInfo getStackInfo(int stackId) {
8564        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8565                "getStackInfo()");
8566        long ident = Binder.clearCallingIdentity();
8567        try {
8568            synchronized (this) {
8569                return mStackSupervisor.getStackInfoLocked(stackId);
8570            }
8571        } finally {
8572            Binder.restoreCallingIdentity(ident);
8573        }
8574    }
8575
8576    @Override
8577    public boolean isInHomeStack(int taskId) {
8578        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8579                "getStackInfo()");
8580        long ident = Binder.clearCallingIdentity();
8581        try {
8582            synchronized (this) {
8583                TaskRecord tr = recentTaskForIdLocked(taskId);
8584                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8585            }
8586        } finally {
8587            Binder.restoreCallingIdentity(ident);
8588        }
8589    }
8590
8591    @Override
8592    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8593        synchronized(this) {
8594            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8595        }
8596    }
8597
8598    private boolean isLockTaskAuthorized(String pkg) {
8599        final DevicePolicyManager dpm = (DevicePolicyManager)
8600                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8601        try {
8602            int uid = mContext.getPackageManager().getPackageUid(pkg,
8603                    Binder.getCallingUserHandle().getIdentifier());
8604            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8605        } catch (NameNotFoundException e) {
8606            return false;
8607        }
8608    }
8609
8610    void startLockTaskMode(TaskRecord task) {
8611        final String pkg;
8612        synchronized (this) {
8613            pkg = task.intent.getComponent().getPackageName();
8614        }
8615        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8616        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8617            final TaskRecord taskRecord = task;
8618            mHandler.post(new Runnable() {
8619                @Override
8620                public void run() {
8621                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8622                }
8623            });
8624            return;
8625        }
8626        long ident = Binder.clearCallingIdentity();
8627        try {
8628            synchronized (this) {
8629                // Since we lost lock on task, make sure it is still there.
8630                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8631                if (task != null) {
8632                    if (!isSystemInitiated
8633                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8634                        throw new IllegalArgumentException("Invalid task, not in foreground");
8635                    }
8636                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8637                }
8638            }
8639        } finally {
8640            Binder.restoreCallingIdentity(ident);
8641        }
8642    }
8643
8644    @Override
8645    public void startLockTaskMode(int taskId) {
8646        final TaskRecord task;
8647        long ident = Binder.clearCallingIdentity();
8648        try {
8649            synchronized (this) {
8650                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8651            }
8652        } finally {
8653            Binder.restoreCallingIdentity(ident);
8654        }
8655        if (task != null) {
8656            startLockTaskMode(task);
8657        }
8658    }
8659
8660    @Override
8661    public void startLockTaskMode(IBinder token) {
8662        final TaskRecord task;
8663        long ident = Binder.clearCallingIdentity();
8664        try {
8665            synchronized (this) {
8666                final ActivityRecord r = ActivityRecord.forToken(token);
8667                if (r == null) {
8668                    return;
8669                }
8670                task = r.task;
8671            }
8672        } finally {
8673            Binder.restoreCallingIdentity(ident);
8674        }
8675        if (task != null) {
8676            startLockTaskMode(task);
8677        }
8678    }
8679
8680    @Override
8681    public void startLockTaskModeOnCurrent() throws RemoteException {
8682        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8683        ActivityRecord r = null;
8684        synchronized (this) {
8685            r = mStackSupervisor.topRunningActivityLocked();
8686        }
8687        startLockTaskMode(r.task);
8688    }
8689
8690    @Override
8691    public void stopLockTaskMode() {
8692        // Verify that the user matches the package of the intent for the TaskRecord
8693        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8694        // and stopLockTaskMode.
8695        final int callingUid = Binder.getCallingUid();
8696        if (callingUid != Process.SYSTEM_UID) {
8697            try {
8698                String pkg =
8699                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8700                int uid = mContext.getPackageManager().getPackageUid(pkg,
8701                        Binder.getCallingUserHandle().getIdentifier());
8702                if (uid != callingUid) {
8703                    throw new SecurityException("Invalid uid, expected " + uid);
8704                }
8705            } catch (NameNotFoundException e) {
8706                Log.d(TAG, "stopLockTaskMode " + e);
8707                return;
8708            }
8709        }
8710        long ident = Binder.clearCallingIdentity();
8711        try {
8712            Log.d(TAG, "stopLockTaskMode");
8713            // Stop lock task
8714            synchronized (this) {
8715                mStackSupervisor.setLockTaskModeLocked(null, false);
8716            }
8717        } finally {
8718            Binder.restoreCallingIdentity(ident);
8719        }
8720    }
8721
8722    @Override
8723    public void stopLockTaskModeOnCurrent() throws RemoteException {
8724        checkCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS);
8725        long ident = Binder.clearCallingIdentity();
8726        try {
8727            stopLockTaskMode();
8728        } finally {
8729            Binder.restoreCallingIdentity(ident);
8730        }
8731    }
8732
8733    @Override
8734    public boolean isInLockTaskMode() {
8735        synchronized (this) {
8736            return mStackSupervisor.isInLockTaskMode();
8737        }
8738    }
8739
8740    // =========================================================
8741    // CONTENT PROVIDERS
8742    // =========================================================
8743
8744    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8745        List<ProviderInfo> providers = null;
8746        try {
8747            providers = AppGlobals.getPackageManager().
8748                queryContentProviders(app.processName, app.uid,
8749                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8750        } catch (RemoteException ex) {
8751        }
8752        if (DEBUG_MU)
8753            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8754        int userId = app.userId;
8755        if (providers != null) {
8756            int N = providers.size();
8757            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8758            for (int i=0; i<N; i++) {
8759                ProviderInfo cpi =
8760                    (ProviderInfo)providers.get(i);
8761                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8762                        cpi.name, cpi.flags);
8763                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8764                    // This is a singleton provider, but a user besides the
8765                    // default user is asking to initialize a process it runs
8766                    // in...  well, no, it doesn't actually run in this process,
8767                    // it runs in the process of the default user.  Get rid of it.
8768                    providers.remove(i);
8769                    N--;
8770                    i--;
8771                    continue;
8772                }
8773
8774                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8775                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8776                if (cpr == null) {
8777                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8778                    mProviderMap.putProviderByClass(comp, cpr);
8779                }
8780                if (DEBUG_MU)
8781                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8782                app.pubProviders.put(cpi.name, cpr);
8783                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8784                    // Don't add this if it is a platform component that is marked
8785                    // to run in multiple processes, because this is actually
8786                    // part of the framework so doesn't make sense to track as a
8787                    // separate apk in the process.
8788                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8789                            mProcessStats);
8790                }
8791                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8792            }
8793        }
8794        return providers;
8795    }
8796
8797    /**
8798     * Check if {@link ProcessRecord} has a possible chance at accessing the
8799     * given {@link ProviderInfo}. Final permission checking is always done
8800     * in {@link ContentProvider}.
8801     */
8802    private final String checkContentProviderPermissionLocked(
8803            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8804        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8805        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8806        boolean checkedGrants = false;
8807        if (checkUser) {
8808            // Looking for cross-user grants before enforcing the typical cross-users permissions
8809            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8810            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8811                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8812                    return null;
8813                }
8814                checkedGrants = true;
8815            }
8816            userId = handleIncomingUser(callingPid, callingUid, userId,
8817                    false, ALLOW_NON_FULL,
8818                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8819            if (userId != tmpTargetUserId) {
8820                // When we actually went to determine the final targer user ID, this ended
8821                // up different than our initial check for the authority.  This is because
8822                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8823                // SELF.  So we need to re-check the grants again.
8824                checkedGrants = false;
8825            }
8826        }
8827        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8828                cpi.applicationInfo.uid, cpi.exported)
8829                == PackageManager.PERMISSION_GRANTED) {
8830            return null;
8831        }
8832        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8833                cpi.applicationInfo.uid, cpi.exported)
8834                == PackageManager.PERMISSION_GRANTED) {
8835            return null;
8836        }
8837
8838        PathPermission[] pps = cpi.pathPermissions;
8839        if (pps != null) {
8840            int i = pps.length;
8841            while (i > 0) {
8842                i--;
8843                PathPermission pp = pps[i];
8844                String pprperm = pp.getReadPermission();
8845                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8846                        cpi.applicationInfo.uid, cpi.exported)
8847                        == PackageManager.PERMISSION_GRANTED) {
8848                    return null;
8849                }
8850                String ppwperm = pp.getWritePermission();
8851                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8852                        cpi.applicationInfo.uid, cpi.exported)
8853                        == PackageManager.PERMISSION_GRANTED) {
8854                    return null;
8855                }
8856            }
8857        }
8858        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8859            return null;
8860        }
8861
8862        String msg;
8863        if (!cpi.exported) {
8864            msg = "Permission Denial: opening provider " + cpi.name
8865                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8866                    + ", uid=" + callingUid + ") that is not exported from uid "
8867                    + cpi.applicationInfo.uid;
8868        } else {
8869            msg = "Permission Denial: opening provider " + cpi.name
8870                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8871                    + ", uid=" + callingUid + ") requires "
8872                    + cpi.readPermission + " or " + cpi.writePermission;
8873        }
8874        Slog.w(TAG, msg);
8875        return msg;
8876    }
8877
8878    /**
8879     * Returns if the ContentProvider has granted a uri to callingUid
8880     */
8881    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8882        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8883        if (perms != null) {
8884            for (int i=perms.size()-1; i>=0; i--) {
8885                GrantUri grantUri = perms.keyAt(i);
8886                if (grantUri.sourceUserId == userId || !checkUser) {
8887                    if (matchesProvider(grantUri.uri, cpi)) {
8888                        return true;
8889                    }
8890                }
8891            }
8892        }
8893        return false;
8894    }
8895
8896    /**
8897     * Returns true if the uri authority is one of the authorities specified in the provider.
8898     */
8899    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8900        String uriAuth = uri.getAuthority();
8901        String cpiAuth = cpi.authority;
8902        if (cpiAuth.indexOf(';') == -1) {
8903            return cpiAuth.equals(uriAuth);
8904        }
8905        String[] cpiAuths = cpiAuth.split(";");
8906        int length = cpiAuths.length;
8907        for (int i = 0; i < length; i++) {
8908            if (cpiAuths[i].equals(uriAuth)) return true;
8909        }
8910        return false;
8911    }
8912
8913    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8914            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8915        if (r != null) {
8916            for (int i=0; i<r.conProviders.size(); i++) {
8917                ContentProviderConnection conn = r.conProviders.get(i);
8918                if (conn.provider == cpr) {
8919                    if (DEBUG_PROVIDER) Slog.v(TAG,
8920                            "Adding provider requested by "
8921                            + r.processName + " from process "
8922                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8923                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8924                    if (stable) {
8925                        conn.stableCount++;
8926                        conn.numStableIncs++;
8927                    } else {
8928                        conn.unstableCount++;
8929                        conn.numUnstableIncs++;
8930                    }
8931                    return conn;
8932                }
8933            }
8934            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8935            if (stable) {
8936                conn.stableCount = 1;
8937                conn.numStableIncs = 1;
8938            } else {
8939                conn.unstableCount = 1;
8940                conn.numUnstableIncs = 1;
8941            }
8942            cpr.connections.add(conn);
8943            r.conProviders.add(conn);
8944            return conn;
8945        }
8946        cpr.addExternalProcessHandleLocked(externalProcessToken);
8947        return null;
8948    }
8949
8950    boolean decProviderCountLocked(ContentProviderConnection conn,
8951            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8952        if (conn != null) {
8953            cpr = conn.provider;
8954            if (DEBUG_PROVIDER) Slog.v(TAG,
8955                    "Removing provider requested by "
8956                    + conn.client.processName + " from process "
8957                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8958                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8959            if (stable) {
8960                conn.stableCount--;
8961            } else {
8962                conn.unstableCount--;
8963            }
8964            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8965                cpr.connections.remove(conn);
8966                conn.client.conProviders.remove(conn);
8967                return true;
8968            }
8969            return false;
8970        }
8971        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8972        return false;
8973    }
8974
8975    private void checkTime(long startTime, String where) {
8976        long now = SystemClock.elapsedRealtime();
8977        if ((now-startTime) > 1000) {
8978            // If we are taking more than a second, log about it.
8979            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
8980        }
8981    }
8982
8983    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8984            String name, IBinder token, boolean stable, int userId) {
8985        ContentProviderRecord cpr;
8986        ContentProviderConnection conn = null;
8987        ProviderInfo cpi = null;
8988
8989        synchronized(this) {
8990            long startTime = SystemClock.elapsedRealtime();
8991
8992            ProcessRecord r = null;
8993            if (caller != null) {
8994                r = getRecordForAppLocked(caller);
8995                if (r == null) {
8996                    throw new SecurityException(
8997                            "Unable to find app for caller " + caller
8998                          + " (pid=" + Binder.getCallingPid()
8999                          + ") when getting content provider " + name);
9000                }
9001            }
9002
9003            boolean checkCrossUser = true;
9004
9005            checkTime(startTime, "getContentProviderImpl: getProviderByName");
9006
9007            // First check if this content provider has been published...
9008            cpr = mProviderMap.getProviderByName(name, userId);
9009            // If that didn't work, check if it exists for user 0 and then
9010            // verify that it's a singleton provider before using it.
9011            if (cpr == null && userId != UserHandle.USER_OWNER) {
9012                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
9013                if (cpr != null) {
9014                    cpi = cpr.info;
9015                    if (isSingleton(cpi.processName, cpi.applicationInfo,
9016                            cpi.name, cpi.flags)
9017                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
9018                        userId = UserHandle.USER_OWNER;
9019                        checkCrossUser = false;
9020                    } else {
9021                        cpr = null;
9022                        cpi = null;
9023                    }
9024                }
9025            }
9026
9027            boolean providerRunning = cpr != null;
9028            if (providerRunning) {
9029                cpi = cpr.info;
9030                String msg;
9031                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9032                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9033                        != null) {
9034                    throw new SecurityException(msg);
9035                }
9036                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9037
9038                if (r != null && cpr.canRunHere(r)) {
9039                    // This provider has been published or is in the process
9040                    // of being published...  but it is also allowed to run
9041                    // in the caller's process, so don't make a connection
9042                    // and just let the caller instantiate its own instance.
9043                    ContentProviderHolder holder = cpr.newHolder(null);
9044                    // don't give caller the provider object, it needs
9045                    // to make its own.
9046                    holder.provider = null;
9047                    return holder;
9048                }
9049
9050                final long origId = Binder.clearCallingIdentity();
9051
9052                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9053
9054                // In this case the provider instance already exists, so we can
9055                // return it right away.
9056                conn = incProviderCountLocked(r, cpr, token, stable);
9057                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9058                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9059                        // If this is a perceptible app accessing the provider,
9060                        // make sure to count it as being accessed and thus
9061                        // back up on the LRU list.  This is good because
9062                        // content providers are often expensive to start.
9063                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9064                        updateLruProcessLocked(cpr.proc, false, null);
9065                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9066                    }
9067                }
9068
9069                if (cpr.proc != null) {
9070                    if (false) {
9071                        if (cpr.name.flattenToShortString().equals(
9072                                "com.android.providers.calendar/.CalendarProvider2")) {
9073                            Slog.v(TAG, "****************** KILLING "
9074                                + cpr.name.flattenToShortString());
9075                            Process.killProcess(cpr.proc.pid);
9076                        }
9077                    }
9078                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9079                    boolean success = updateOomAdjLocked(cpr.proc);
9080                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9081                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9082                    // NOTE: there is still a race here where a signal could be
9083                    // pending on the process even though we managed to update its
9084                    // adj level.  Not sure what to do about this, but at least
9085                    // the race is now smaller.
9086                    if (!success) {
9087                        // Uh oh...  it looks like the provider's process
9088                        // has been killed on us.  We need to wait for a new
9089                        // process to be started, and make sure its death
9090                        // doesn't kill our process.
9091                        Slog.i(TAG,
9092                                "Existing provider " + cpr.name.flattenToShortString()
9093                                + " is crashing; detaching " + r);
9094                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9095                        checkTime(startTime, "getContentProviderImpl: before appDied");
9096                        appDiedLocked(cpr.proc);
9097                        checkTime(startTime, "getContentProviderImpl: after appDied");
9098                        if (!lastRef) {
9099                            // This wasn't the last ref our process had on
9100                            // the provider...  we have now been killed, bail.
9101                            return null;
9102                        }
9103                        providerRunning = false;
9104                        conn = null;
9105                    }
9106                }
9107
9108                Binder.restoreCallingIdentity(origId);
9109            }
9110
9111            boolean singleton;
9112            if (!providerRunning) {
9113                try {
9114                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9115                    cpi = AppGlobals.getPackageManager().
9116                        resolveContentProvider(name,
9117                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9118                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9119                } catch (RemoteException ex) {
9120                }
9121                if (cpi == null) {
9122                    return null;
9123                }
9124                // If the provider is a singleton AND
9125                // (it's a call within the same user || the provider is a
9126                // privileged app)
9127                // Then allow connecting to the singleton provider
9128                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9129                        cpi.name, cpi.flags)
9130                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9131                if (singleton) {
9132                    userId = UserHandle.USER_OWNER;
9133                }
9134                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9135                checkTime(startTime, "getContentProviderImpl: got app info for user");
9136
9137                String msg;
9138                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9139                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9140                        != null) {
9141                    throw new SecurityException(msg);
9142                }
9143                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9144
9145                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9146                        && !cpi.processName.equals("system")) {
9147                    // If this content provider does not run in the system
9148                    // process, and the system is not yet ready to run other
9149                    // processes, then fail fast instead of hanging.
9150                    throw new IllegalArgumentException(
9151                            "Attempt to launch content provider before system ready");
9152                }
9153
9154                // Make sure that the user who owns this provider is started.  If not,
9155                // we don't want to allow it to run.
9156                if (mStartedUsers.get(userId) == null) {
9157                    Slog.w(TAG, "Unable to launch app "
9158                            + cpi.applicationInfo.packageName + "/"
9159                            + cpi.applicationInfo.uid + " for provider "
9160                            + name + ": user " + userId + " is stopped");
9161                    return null;
9162                }
9163
9164                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9165                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9166                cpr = mProviderMap.getProviderByClass(comp, userId);
9167                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9168                final boolean firstClass = cpr == null;
9169                if (firstClass) {
9170                    try {
9171                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9172                        ApplicationInfo ai =
9173                            AppGlobals.getPackageManager().
9174                                getApplicationInfo(
9175                                        cpi.applicationInfo.packageName,
9176                                        STOCK_PM_FLAGS, userId);
9177                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9178                        if (ai == null) {
9179                            Slog.w(TAG, "No package info for content provider "
9180                                    + cpi.name);
9181                            return null;
9182                        }
9183                        ai = getAppInfoForUser(ai, userId);
9184                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9185                    } catch (RemoteException ex) {
9186                        // pm is in same process, this will never happen.
9187                    }
9188                }
9189
9190                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9191
9192                if (r != null && cpr.canRunHere(r)) {
9193                    // If this is a multiprocess provider, then just return its
9194                    // info and allow the caller to instantiate it.  Only do
9195                    // this if the provider is the same user as the caller's
9196                    // process, or can run as root (so can be in any process).
9197                    return cpr.newHolder(null);
9198                }
9199
9200                if (DEBUG_PROVIDER) {
9201                    RuntimeException e = new RuntimeException("here");
9202                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9203                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9204                }
9205
9206                // This is single process, and our app is now connecting to it.
9207                // See if we are already in the process of launching this
9208                // provider.
9209                final int N = mLaunchingProviders.size();
9210                int i;
9211                for (i=0; i<N; i++) {
9212                    if (mLaunchingProviders.get(i) == cpr) {
9213                        break;
9214                    }
9215                }
9216
9217                // If the provider is not already being launched, then get it
9218                // started.
9219                if (i >= N) {
9220                    final long origId = Binder.clearCallingIdentity();
9221
9222                    try {
9223                        // Content provider is now in use, its package can't be stopped.
9224                        try {
9225                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9226                            AppGlobals.getPackageManager().setPackageStoppedState(
9227                                    cpr.appInfo.packageName, false, userId);
9228                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9229                        } catch (RemoteException e) {
9230                        } catch (IllegalArgumentException e) {
9231                            Slog.w(TAG, "Failed trying to unstop package "
9232                                    + cpr.appInfo.packageName + ": " + e);
9233                        }
9234
9235                        // Use existing process if already started
9236                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9237                        ProcessRecord proc = getProcessRecordLocked(
9238                                cpi.processName, cpr.appInfo.uid, false);
9239                        if (proc != null && proc.thread != null) {
9240                            if (DEBUG_PROVIDER) {
9241                                Slog.d(TAG, "Installing in existing process " + proc);
9242                            }
9243                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9244                            proc.pubProviders.put(cpi.name, cpr);
9245                            try {
9246                                proc.thread.scheduleInstallProvider(cpi);
9247                            } catch (RemoteException e) {
9248                            }
9249                        } else {
9250                            checkTime(startTime, "getContentProviderImpl: before start process");
9251                            proc = startProcessLocked(cpi.processName,
9252                                    cpr.appInfo, false, 0, "content provider",
9253                                    new ComponentName(cpi.applicationInfo.packageName,
9254                                            cpi.name), false, false, false);
9255                            checkTime(startTime, "getContentProviderImpl: after start process");
9256                            if (proc == null) {
9257                                Slog.w(TAG, "Unable to launch app "
9258                                        + cpi.applicationInfo.packageName + "/"
9259                                        + cpi.applicationInfo.uid + " for provider "
9260                                        + name + ": process is bad");
9261                                return null;
9262                            }
9263                        }
9264                        cpr.launchingApp = proc;
9265                        mLaunchingProviders.add(cpr);
9266                    } finally {
9267                        Binder.restoreCallingIdentity(origId);
9268                    }
9269                }
9270
9271                checkTime(startTime, "getContentProviderImpl: updating data structures");
9272
9273                // Make sure the provider is published (the same provider class
9274                // may be published under multiple names).
9275                if (firstClass) {
9276                    mProviderMap.putProviderByClass(comp, cpr);
9277                }
9278
9279                mProviderMap.putProviderByName(name, cpr);
9280                conn = incProviderCountLocked(r, cpr, token, stable);
9281                if (conn != null) {
9282                    conn.waiting = true;
9283                }
9284            }
9285            checkTime(startTime, "getContentProviderImpl: done!");
9286        }
9287
9288        // Wait for the provider to be published...
9289        synchronized (cpr) {
9290            while (cpr.provider == null) {
9291                if (cpr.launchingApp == null) {
9292                    Slog.w(TAG, "Unable to launch app "
9293                            + cpi.applicationInfo.packageName + "/"
9294                            + cpi.applicationInfo.uid + " for provider "
9295                            + name + ": launching app became null");
9296                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9297                            UserHandle.getUserId(cpi.applicationInfo.uid),
9298                            cpi.applicationInfo.packageName,
9299                            cpi.applicationInfo.uid, name);
9300                    return null;
9301                }
9302                try {
9303                    if (DEBUG_MU) {
9304                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9305                                + cpr.launchingApp);
9306                    }
9307                    if (conn != null) {
9308                        conn.waiting = true;
9309                    }
9310                    cpr.wait();
9311                } catch (InterruptedException ex) {
9312                } finally {
9313                    if (conn != null) {
9314                        conn.waiting = false;
9315                    }
9316                }
9317            }
9318        }
9319        return cpr != null ? cpr.newHolder(conn) : null;
9320    }
9321
9322    @Override
9323    public final ContentProviderHolder getContentProvider(
9324            IApplicationThread caller, String name, int userId, boolean stable) {
9325        enforceNotIsolatedCaller("getContentProvider");
9326        if (caller == null) {
9327            String msg = "null IApplicationThread when getting content provider "
9328                    + name;
9329            Slog.w(TAG, msg);
9330            throw new SecurityException(msg);
9331        }
9332        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9333        // with cross-user grant.
9334        return getContentProviderImpl(caller, name, null, stable, userId);
9335    }
9336
9337    public ContentProviderHolder getContentProviderExternal(
9338            String name, int userId, IBinder token) {
9339        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9340            "Do not have permission in call getContentProviderExternal()");
9341        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9342                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9343        return getContentProviderExternalUnchecked(name, token, userId);
9344    }
9345
9346    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9347            IBinder token, int userId) {
9348        return getContentProviderImpl(null, name, token, true, userId);
9349    }
9350
9351    /**
9352     * Drop a content provider from a ProcessRecord's bookkeeping
9353     */
9354    public void removeContentProvider(IBinder connection, boolean stable) {
9355        enforceNotIsolatedCaller("removeContentProvider");
9356        long ident = Binder.clearCallingIdentity();
9357        try {
9358            synchronized (this) {
9359                ContentProviderConnection conn;
9360                try {
9361                    conn = (ContentProviderConnection)connection;
9362                } catch (ClassCastException e) {
9363                    String msg ="removeContentProvider: " + connection
9364                            + " not a ContentProviderConnection";
9365                    Slog.w(TAG, msg);
9366                    throw new IllegalArgumentException(msg);
9367                }
9368                if (conn == null) {
9369                    throw new NullPointerException("connection is null");
9370                }
9371                if (decProviderCountLocked(conn, null, null, stable)) {
9372                    updateOomAdjLocked();
9373                }
9374            }
9375        } finally {
9376            Binder.restoreCallingIdentity(ident);
9377        }
9378    }
9379
9380    public void removeContentProviderExternal(String name, IBinder token) {
9381        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9382            "Do not have permission in call removeContentProviderExternal()");
9383        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9384    }
9385
9386    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9387        synchronized (this) {
9388            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9389            if(cpr == null) {
9390                //remove from mProvidersByClass
9391                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9392                return;
9393            }
9394
9395            //update content provider record entry info
9396            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9397            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9398            if (localCpr.hasExternalProcessHandles()) {
9399                if (localCpr.removeExternalProcessHandleLocked(token)) {
9400                    updateOomAdjLocked();
9401                } else {
9402                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9403                            + " with no external reference for token: "
9404                            + token + ".");
9405                }
9406            } else {
9407                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9408                        + " with no external references.");
9409            }
9410        }
9411    }
9412
9413    public final void publishContentProviders(IApplicationThread caller,
9414            List<ContentProviderHolder> providers) {
9415        if (providers == null) {
9416            return;
9417        }
9418
9419        enforceNotIsolatedCaller("publishContentProviders");
9420        synchronized (this) {
9421            final ProcessRecord r = getRecordForAppLocked(caller);
9422            if (DEBUG_MU)
9423                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9424            if (r == null) {
9425                throw new SecurityException(
9426                        "Unable to find app for caller " + caller
9427                      + " (pid=" + Binder.getCallingPid()
9428                      + ") when publishing content providers");
9429            }
9430
9431            final long origId = Binder.clearCallingIdentity();
9432
9433            final int N = providers.size();
9434            for (int i=0; i<N; i++) {
9435                ContentProviderHolder src = providers.get(i);
9436                if (src == null || src.info == null || src.provider == null) {
9437                    continue;
9438                }
9439                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9440                if (DEBUG_MU)
9441                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9442                if (dst != null) {
9443                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9444                    mProviderMap.putProviderByClass(comp, dst);
9445                    String names[] = dst.info.authority.split(";");
9446                    for (int j = 0; j < names.length; j++) {
9447                        mProviderMap.putProviderByName(names[j], dst);
9448                    }
9449
9450                    int NL = mLaunchingProviders.size();
9451                    int j;
9452                    for (j=0; j<NL; j++) {
9453                        if (mLaunchingProviders.get(j) == dst) {
9454                            mLaunchingProviders.remove(j);
9455                            j--;
9456                            NL--;
9457                        }
9458                    }
9459                    synchronized (dst) {
9460                        dst.provider = src.provider;
9461                        dst.proc = r;
9462                        dst.notifyAll();
9463                    }
9464                    updateOomAdjLocked(r);
9465                }
9466            }
9467
9468            Binder.restoreCallingIdentity(origId);
9469        }
9470    }
9471
9472    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9473        ContentProviderConnection conn;
9474        try {
9475            conn = (ContentProviderConnection)connection;
9476        } catch (ClassCastException e) {
9477            String msg ="refContentProvider: " + connection
9478                    + " not a ContentProviderConnection";
9479            Slog.w(TAG, msg);
9480            throw new IllegalArgumentException(msg);
9481        }
9482        if (conn == null) {
9483            throw new NullPointerException("connection is null");
9484        }
9485
9486        synchronized (this) {
9487            if (stable > 0) {
9488                conn.numStableIncs += stable;
9489            }
9490            stable = conn.stableCount + stable;
9491            if (stable < 0) {
9492                throw new IllegalStateException("stableCount < 0: " + stable);
9493            }
9494
9495            if (unstable > 0) {
9496                conn.numUnstableIncs += unstable;
9497            }
9498            unstable = conn.unstableCount + unstable;
9499            if (unstable < 0) {
9500                throw new IllegalStateException("unstableCount < 0: " + unstable);
9501            }
9502
9503            if ((stable+unstable) <= 0) {
9504                throw new IllegalStateException("ref counts can't go to zero here: stable="
9505                        + stable + " unstable=" + unstable);
9506            }
9507            conn.stableCount = stable;
9508            conn.unstableCount = unstable;
9509            return !conn.dead;
9510        }
9511    }
9512
9513    public void unstableProviderDied(IBinder connection) {
9514        ContentProviderConnection conn;
9515        try {
9516            conn = (ContentProviderConnection)connection;
9517        } catch (ClassCastException e) {
9518            String msg ="refContentProvider: " + connection
9519                    + " not a ContentProviderConnection";
9520            Slog.w(TAG, msg);
9521            throw new IllegalArgumentException(msg);
9522        }
9523        if (conn == null) {
9524            throw new NullPointerException("connection is null");
9525        }
9526
9527        // Safely retrieve the content provider associated with the connection.
9528        IContentProvider provider;
9529        synchronized (this) {
9530            provider = conn.provider.provider;
9531        }
9532
9533        if (provider == null) {
9534            // Um, yeah, we're way ahead of you.
9535            return;
9536        }
9537
9538        // Make sure the caller is being honest with us.
9539        if (provider.asBinder().pingBinder()) {
9540            // Er, no, still looks good to us.
9541            synchronized (this) {
9542                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9543                        + " says " + conn + " died, but we don't agree");
9544                return;
9545            }
9546        }
9547
9548        // Well look at that!  It's dead!
9549        synchronized (this) {
9550            if (conn.provider.provider != provider) {
9551                // But something changed...  good enough.
9552                return;
9553            }
9554
9555            ProcessRecord proc = conn.provider.proc;
9556            if (proc == null || proc.thread == null) {
9557                // Seems like the process is already cleaned up.
9558                return;
9559            }
9560
9561            // As far as we're concerned, this is just like receiving a
9562            // death notification...  just a bit prematurely.
9563            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9564                    + ") early provider death");
9565            final long ident = Binder.clearCallingIdentity();
9566            try {
9567                appDiedLocked(proc);
9568            } finally {
9569                Binder.restoreCallingIdentity(ident);
9570            }
9571        }
9572    }
9573
9574    @Override
9575    public void appNotRespondingViaProvider(IBinder connection) {
9576        enforceCallingPermission(
9577                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9578
9579        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9580        if (conn == null) {
9581            Slog.w(TAG, "ContentProviderConnection is null");
9582            return;
9583        }
9584
9585        final ProcessRecord host = conn.provider.proc;
9586        if (host == null) {
9587            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9588            return;
9589        }
9590
9591        final long token = Binder.clearCallingIdentity();
9592        try {
9593            appNotResponding(host, null, null, false, "ContentProvider not responding");
9594        } finally {
9595            Binder.restoreCallingIdentity(token);
9596        }
9597    }
9598
9599    public final void installSystemProviders() {
9600        List<ProviderInfo> providers;
9601        synchronized (this) {
9602            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9603            providers = generateApplicationProvidersLocked(app);
9604            if (providers != null) {
9605                for (int i=providers.size()-1; i>=0; i--) {
9606                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9607                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9608                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9609                                + ": not system .apk");
9610                        providers.remove(i);
9611                    }
9612                }
9613            }
9614        }
9615        if (providers != null) {
9616            mSystemThread.installSystemProviders(providers);
9617        }
9618
9619        mCoreSettingsObserver = new CoreSettingsObserver(this);
9620
9621        //mUsageStatsService.monitorPackages();
9622    }
9623
9624    /**
9625     * Allows apps to retrieve the MIME type of a URI.
9626     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9627     * users, then it does not need permission to access the ContentProvider.
9628     * Either, it needs cross-user uri grants.
9629     *
9630     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9631     *
9632     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9633     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9634     */
9635    public String getProviderMimeType(Uri uri, int userId) {
9636        enforceNotIsolatedCaller("getProviderMimeType");
9637        final String name = uri.getAuthority();
9638        int callingUid = Binder.getCallingUid();
9639        int callingPid = Binder.getCallingPid();
9640        long ident = 0;
9641        boolean clearedIdentity = false;
9642        userId = unsafeConvertIncomingUser(userId);
9643        if (UserHandle.getUserId(callingUid) != userId) {
9644            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9645                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9646                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9647                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9648                clearedIdentity = true;
9649                ident = Binder.clearCallingIdentity();
9650            }
9651        }
9652        ContentProviderHolder holder = null;
9653        try {
9654            holder = getContentProviderExternalUnchecked(name, null, userId);
9655            if (holder != null) {
9656                return holder.provider.getType(uri);
9657            }
9658        } catch (RemoteException e) {
9659            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9660            return null;
9661        } finally {
9662            // We need to clear the identity to call removeContentProviderExternalUnchecked
9663            if (!clearedIdentity) {
9664                ident = Binder.clearCallingIdentity();
9665            }
9666            try {
9667                if (holder != null) {
9668                    removeContentProviderExternalUnchecked(name, null, userId);
9669                }
9670            } finally {
9671                Binder.restoreCallingIdentity(ident);
9672            }
9673        }
9674
9675        return null;
9676    }
9677
9678    // =========================================================
9679    // GLOBAL MANAGEMENT
9680    // =========================================================
9681
9682    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9683            boolean isolated, int isolatedUid) {
9684        String proc = customProcess != null ? customProcess : info.processName;
9685        BatteryStatsImpl.Uid.Proc ps = null;
9686        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9687        int uid = info.uid;
9688        if (isolated) {
9689            if (isolatedUid == 0) {
9690                int userId = UserHandle.getUserId(uid);
9691                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9692                while (true) {
9693                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9694                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9695                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9696                    }
9697                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9698                    mNextIsolatedProcessUid++;
9699                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9700                        // No process for this uid, use it.
9701                        break;
9702                    }
9703                    stepsLeft--;
9704                    if (stepsLeft <= 0) {
9705                        return null;
9706                    }
9707                }
9708            } else {
9709                // Special case for startIsolatedProcess (internal only), where
9710                // the uid of the isolated process is specified by the caller.
9711                uid = isolatedUid;
9712            }
9713        }
9714        return new ProcessRecord(stats, info, proc, uid);
9715    }
9716
9717    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9718            String abiOverride) {
9719        ProcessRecord app;
9720        if (!isolated) {
9721            app = getProcessRecordLocked(info.processName, info.uid, true);
9722        } else {
9723            app = null;
9724        }
9725
9726        if (app == null) {
9727            app = newProcessRecordLocked(info, null, isolated, 0);
9728            mProcessNames.put(info.processName, app.uid, app);
9729            if (isolated) {
9730                mIsolatedProcesses.put(app.uid, app);
9731            }
9732            updateLruProcessLocked(app, false, null);
9733            updateOomAdjLocked();
9734        }
9735
9736        // This package really, really can not be stopped.
9737        try {
9738            AppGlobals.getPackageManager().setPackageStoppedState(
9739                    info.packageName, false, UserHandle.getUserId(app.uid));
9740        } catch (RemoteException e) {
9741        } catch (IllegalArgumentException e) {
9742            Slog.w(TAG, "Failed trying to unstop package "
9743                    + info.packageName + ": " + e);
9744        }
9745
9746        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9747                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9748            app.persistent = true;
9749            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9750        }
9751        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9752            mPersistentStartingProcesses.add(app);
9753            startProcessLocked(app, "added application", app.processName, abiOverride,
9754                    null /* entryPoint */, null /* entryPointArgs */);
9755        }
9756
9757        return app;
9758    }
9759
9760    public void unhandledBack() {
9761        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9762                "unhandledBack()");
9763
9764        synchronized(this) {
9765            final long origId = Binder.clearCallingIdentity();
9766            try {
9767                getFocusedStack().unhandledBackLocked();
9768            } finally {
9769                Binder.restoreCallingIdentity(origId);
9770            }
9771        }
9772    }
9773
9774    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9775        enforceNotIsolatedCaller("openContentUri");
9776        final int userId = UserHandle.getCallingUserId();
9777        String name = uri.getAuthority();
9778        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9779        ParcelFileDescriptor pfd = null;
9780        if (cph != null) {
9781            // We record the binder invoker's uid in thread-local storage before
9782            // going to the content provider to open the file.  Later, in the code
9783            // that handles all permissions checks, we look for this uid and use
9784            // that rather than the Activity Manager's own uid.  The effect is that
9785            // we do the check against the caller's permissions even though it looks
9786            // to the content provider like the Activity Manager itself is making
9787            // the request.
9788            sCallerIdentity.set(new Identity(
9789                    Binder.getCallingPid(), Binder.getCallingUid()));
9790            try {
9791                pfd = cph.provider.openFile(null, uri, "r", null);
9792            } catch (FileNotFoundException e) {
9793                // do nothing; pfd will be returned null
9794            } finally {
9795                // Ensure that whatever happens, we clean up the identity state
9796                sCallerIdentity.remove();
9797            }
9798
9799            // We've got the fd now, so we're done with the provider.
9800            removeContentProviderExternalUnchecked(name, null, userId);
9801        } else {
9802            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9803        }
9804        return pfd;
9805    }
9806
9807    // Actually is sleeping or shutting down or whatever else in the future
9808    // is an inactive state.
9809    public boolean isSleepingOrShuttingDown() {
9810        return mSleeping || mShuttingDown;
9811    }
9812
9813    public boolean isSleeping() {
9814        return mSleeping;
9815    }
9816
9817    void goingToSleep() {
9818        synchronized(this) {
9819            mWentToSleep = true;
9820            updateEventDispatchingLocked();
9821            goToSleepIfNeededLocked();
9822        }
9823    }
9824
9825    void finishRunningVoiceLocked() {
9826        if (mRunningVoice) {
9827            mRunningVoice = false;
9828            goToSleepIfNeededLocked();
9829        }
9830    }
9831
9832    void goToSleepIfNeededLocked() {
9833        if (mWentToSleep && !mRunningVoice) {
9834            if (!mSleeping) {
9835                mSleeping = true;
9836                mStackSupervisor.goingToSleepLocked();
9837
9838                // Initialize the wake times of all processes.
9839                checkExcessivePowerUsageLocked(false);
9840                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9841                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9842                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9843            }
9844        }
9845    }
9846
9847    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9848        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9849            // Never persist the home stack.
9850            return;
9851        }
9852        mTaskPersister.wakeup(task, flush);
9853    }
9854
9855    @Override
9856    public boolean shutdown(int timeout) {
9857        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9858                != PackageManager.PERMISSION_GRANTED) {
9859            throw new SecurityException("Requires permission "
9860                    + android.Manifest.permission.SHUTDOWN);
9861        }
9862
9863        boolean timedout = false;
9864
9865        synchronized(this) {
9866            mShuttingDown = true;
9867            updateEventDispatchingLocked();
9868            timedout = mStackSupervisor.shutdownLocked(timeout);
9869        }
9870
9871        mAppOpsService.shutdown();
9872        if (mUsageStatsService != null) {
9873            mUsageStatsService.prepareShutdown();
9874        }
9875        mBatteryStatsService.shutdown();
9876        synchronized (this) {
9877            mProcessStats.shutdownLocked();
9878        }
9879        notifyTaskPersisterLocked(null, true);
9880
9881        return timedout;
9882    }
9883
9884    public final void activitySlept(IBinder token) {
9885        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9886
9887        final long origId = Binder.clearCallingIdentity();
9888
9889        synchronized (this) {
9890            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9891            if (r != null) {
9892                mStackSupervisor.activitySleptLocked(r);
9893            }
9894        }
9895
9896        Binder.restoreCallingIdentity(origId);
9897    }
9898
9899    void logLockScreen(String msg) {
9900        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9901                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9902                mWentToSleep + " mSleeping=" + mSleeping);
9903    }
9904
9905    private void comeOutOfSleepIfNeededLocked() {
9906        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9907            if (mSleeping) {
9908                mSleeping = false;
9909                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9910            }
9911        }
9912    }
9913
9914    void wakingUp() {
9915        synchronized(this) {
9916            mWentToSleep = false;
9917            updateEventDispatchingLocked();
9918            comeOutOfSleepIfNeededLocked();
9919        }
9920    }
9921
9922    void startRunningVoiceLocked() {
9923        if (!mRunningVoice) {
9924            mRunningVoice = true;
9925            comeOutOfSleepIfNeededLocked();
9926        }
9927    }
9928
9929    private void updateEventDispatchingLocked() {
9930        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9931    }
9932
9933    public void setLockScreenShown(boolean shown) {
9934        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9935                != PackageManager.PERMISSION_GRANTED) {
9936            throw new SecurityException("Requires permission "
9937                    + android.Manifest.permission.DEVICE_POWER);
9938        }
9939
9940        synchronized(this) {
9941            long ident = Binder.clearCallingIdentity();
9942            try {
9943                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9944                mLockScreenShown = shown;
9945                comeOutOfSleepIfNeededLocked();
9946            } finally {
9947                Binder.restoreCallingIdentity(ident);
9948            }
9949        }
9950    }
9951
9952    @Override
9953    public void stopAppSwitches() {
9954        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9955                != PackageManager.PERMISSION_GRANTED) {
9956            throw new SecurityException("Requires permission "
9957                    + android.Manifest.permission.STOP_APP_SWITCHES);
9958        }
9959
9960        synchronized(this) {
9961            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9962                    + APP_SWITCH_DELAY_TIME;
9963            mDidAppSwitch = false;
9964            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9965            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9966            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9967        }
9968    }
9969
9970    public void resumeAppSwitches() {
9971        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9972                != PackageManager.PERMISSION_GRANTED) {
9973            throw new SecurityException("Requires permission "
9974                    + android.Manifest.permission.STOP_APP_SWITCHES);
9975        }
9976
9977        synchronized(this) {
9978            // Note that we don't execute any pending app switches... we will
9979            // let those wait until either the timeout, or the next start
9980            // activity request.
9981            mAppSwitchesAllowedTime = 0;
9982        }
9983    }
9984
9985    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9986            String name) {
9987        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9988            return true;
9989        }
9990
9991        final int perm = checkComponentPermission(
9992                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9993                callingUid, -1, true);
9994        if (perm == PackageManager.PERMISSION_GRANTED) {
9995            return true;
9996        }
9997
9998        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9999        return false;
10000    }
10001
10002    public void setDebugApp(String packageName, boolean waitForDebugger,
10003            boolean persistent) {
10004        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
10005                "setDebugApp()");
10006
10007        long ident = Binder.clearCallingIdentity();
10008        try {
10009            // Note that this is not really thread safe if there are multiple
10010            // callers into it at the same time, but that's not a situation we
10011            // care about.
10012            if (persistent) {
10013                final ContentResolver resolver = mContext.getContentResolver();
10014                Settings.Global.putString(
10015                    resolver, Settings.Global.DEBUG_APP,
10016                    packageName);
10017                Settings.Global.putInt(
10018                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
10019                    waitForDebugger ? 1 : 0);
10020            }
10021
10022            synchronized (this) {
10023                if (!persistent) {
10024                    mOrigDebugApp = mDebugApp;
10025                    mOrigWaitForDebugger = mWaitForDebugger;
10026                }
10027                mDebugApp = packageName;
10028                mWaitForDebugger = waitForDebugger;
10029                mDebugTransient = !persistent;
10030                if (packageName != null) {
10031                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10032                            false, UserHandle.USER_ALL, "set debug app");
10033                }
10034            }
10035        } finally {
10036            Binder.restoreCallingIdentity(ident);
10037        }
10038    }
10039
10040    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10041        synchronized (this) {
10042            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10043            if (!isDebuggable) {
10044                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10045                    throw new SecurityException("Process not debuggable: " + app.packageName);
10046                }
10047            }
10048
10049            mOpenGlTraceApp = processName;
10050        }
10051    }
10052
10053    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10054        synchronized (this) {
10055            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10056            if (!isDebuggable) {
10057                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10058                    throw new SecurityException("Process not debuggable: " + app.packageName);
10059                }
10060            }
10061            mProfileApp = processName;
10062            mProfileFile = profilerInfo.profileFile;
10063            if (mProfileFd != null) {
10064                try {
10065                    mProfileFd.close();
10066                } catch (IOException e) {
10067                }
10068                mProfileFd = null;
10069            }
10070            mProfileFd = profilerInfo.profileFd;
10071            mSamplingInterval = profilerInfo.samplingInterval;
10072            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10073            mProfileType = 0;
10074        }
10075    }
10076
10077    @Override
10078    public void setAlwaysFinish(boolean enabled) {
10079        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10080                "setAlwaysFinish()");
10081
10082        Settings.Global.putInt(
10083                mContext.getContentResolver(),
10084                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10085
10086        synchronized (this) {
10087            mAlwaysFinishActivities = enabled;
10088        }
10089    }
10090
10091    @Override
10092    public void setActivityController(IActivityController controller) {
10093        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10094                "setActivityController()");
10095        synchronized (this) {
10096            mController = controller;
10097            Watchdog.getInstance().setActivityController(controller);
10098        }
10099    }
10100
10101    @Override
10102    public void setUserIsMonkey(boolean userIsMonkey) {
10103        synchronized (this) {
10104            synchronized (mPidsSelfLocked) {
10105                final int callingPid = Binder.getCallingPid();
10106                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10107                if (precessRecord == null) {
10108                    throw new SecurityException("Unknown process: " + callingPid);
10109                }
10110                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10111                    throw new SecurityException("Only an instrumentation process "
10112                            + "with a UiAutomation can call setUserIsMonkey");
10113                }
10114            }
10115            mUserIsMonkey = userIsMonkey;
10116        }
10117    }
10118
10119    @Override
10120    public boolean isUserAMonkey() {
10121        synchronized (this) {
10122            // If there is a controller also implies the user is a monkey.
10123            return (mUserIsMonkey || mController != null);
10124        }
10125    }
10126
10127    public void requestBugReport() {
10128        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10129        SystemProperties.set("ctl.start", "bugreport");
10130    }
10131
10132    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10133        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10134    }
10135
10136    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10137        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10138            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10139        }
10140        return KEY_DISPATCHING_TIMEOUT;
10141    }
10142
10143    @Override
10144    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10145        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10146                != PackageManager.PERMISSION_GRANTED) {
10147            throw new SecurityException("Requires permission "
10148                    + android.Manifest.permission.FILTER_EVENTS);
10149        }
10150        ProcessRecord proc;
10151        long timeout;
10152        synchronized (this) {
10153            synchronized (mPidsSelfLocked) {
10154                proc = mPidsSelfLocked.get(pid);
10155            }
10156            timeout = getInputDispatchingTimeoutLocked(proc);
10157        }
10158
10159        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10160            return -1;
10161        }
10162
10163        return timeout;
10164    }
10165
10166    /**
10167     * Handle input dispatching timeouts.
10168     * Returns whether input dispatching should be aborted or not.
10169     */
10170    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10171            final ActivityRecord activity, final ActivityRecord parent,
10172            final boolean aboveSystem, String reason) {
10173        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10174                != PackageManager.PERMISSION_GRANTED) {
10175            throw new SecurityException("Requires permission "
10176                    + android.Manifest.permission.FILTER_EVENTS);
10177        }
10178
10179        final String annotation;
10180        if (reason == null) {
10181            annotation = "Input dispatching timed out";
10182        } else {
10183            annotation = "Input dispatching timed out (" + reason + ")";
10184        }
10185
10186        if (proc != null) {
10187            synchronized (this) {
10188                if (proc.debugging) {
10189                    return false;
10190                }
10191
10192                if (mDidDexOpt) {
10193                    // Give more time since we were dexopting.
10194                    mDidDexOpt = false;
10195                    return false;
10196                }
10197
10198                if (proc.instrumentationClass != null) {
10199                    Bundle info = new Bundle();
10200                    info.putString("shortMsg", "keyDispatchingTimedOut");
10201                    info.putString("longMsg", annotation);
10202                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10203                    return true;
10204                }
10205            }
10206            mHandler.post(new Runnable() {
10207                @Override
10208                public void run() {
10209                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10210                }
10211            });
10212        }
10213
10214        return true;
10215    }
10216
10217    public Bundle getAssistContextExtras(int requestType) {
10218        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10219                "getAssistContextExtras()");
10220        PendingAssistExtras pae;
10221        Bundle extras = new Bundle();
10222        synchronized (this) {
10223            ActivityRecord activity = getFocusedStack().mResumedActivity;
10224            if (activity == null) {
10225                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10226                return null;
10227            }
10228            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10229            if (activity.app == null || activity.app.thread == null) {
10230                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10231                return extras;
10232            }
10233            if (activity.app.pid == Binder.getCallingPid()) {
10234                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10235                return extras;
10236            }
10237            pae = new PendingAssistExtras(activity);
10238            try {
10239                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10240                        requestType);
10241                mPendingAssistExtras.add(pae);
10242                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10243            } catch (RemoteException e) {
10244                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10245                return extras;
10246            }
10247        }
10248        synchronized (pae) {
10249            while (!pae.haveResult) {
10250                try {
10251                    pae.wait();
10252                } catch (InterruptedException e) {
10253                }
10254            }
10255            if (pae.result != null) {
10256                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10257            }
10258        }
10259        synchronized (this) {
10260            mPendingAssistExtras.remove(pae);
10261            mHandler.removeCallbacks(pae);
10262        }
10263        return extras;
10264    }
10265
10266    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10267        PendingAssistExtras pae = (PendingAssistExtras)token;
10268        synchronized (pae) {
10269            pae.result = extras;
10270            pae.haveResult = true;
10271            pae.notifyAll();
10272        }
10273    }
10274
10275    public void registerProcessObserver(IProcessObserver observer) {
10276        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10277                "registerProcessObserver()");
10278        synchronized (this) {
10279            mProcessObservers.register(observer);
10280        }
10281    }
10282
10283    @Override
10284    public void unregisterProcessObserver(IProcessObserver observer) {
10285        synchronized (this) {
10286            mProcessObservers.unregister(observer);
10287        }
10288    }
10289
10290    @Override
10291    public boolean convertFromTranslucent(IBinder token) {
10292        final long origId = Binder.clearCallingIdentity();
10293        try {
10294            synchronized (this) {
10295                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10296                if (r == null) {
10297                    return false;
10298                }
10299                if (r.changeWindowTranslucency(true)) {
10300                    mWindowManager.setAppFullscreen(token, true);
10301                    r.task.stack.releaseBackgroundResources();
10302                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10303                    return true;
10304                }
10305                return false;
10306            }
10307        } finally {
10308            Binder.restoreCallingIdentity(origId);
10309        }
10310    }
10311
10312    @Override
10313    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
10314        final long origId = Binder.clearCallingIdentity();
10315        try {
10316            synchronized (this) {
10317                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10318                if (r == null) {
10319                    return false;
10320                }
10321                int index = r.task.mActivities.lastIndexOf(r);
10322                if (index > 0) {
10323                    ActivityRecord under = r.task.mActivities.get(index - 1);
10324                    under.returningOptions = options;
10325                }
10326                if (r.changeWindowTranslucency(false)) {
10327                    r.task.stack.convertToTranslucent(r);
10328                    mWindowManager.setAppFullscreen(token, false);
10329                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10330                    return true;
10331                } else {
10332                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10333                    return false;
10334                }
10335            }
10336        } finally {
10337            Binder.restoreCallingIdentity(origId);
10338        }
10339    }
10340
10341    @Override
10342    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10343        final long origId = Binder.clearCallingIdentity();
10344        try {
10345            synchronized (this) {
10346                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10347                if (r != null) {
10348                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10349                }
10350            }
10351            return false;
10352        } finally {
10353            Binder.restoreCallingIdentity(origId);
10354        }
10355    }
10356
10357    @Override
10358    public boolean isBackgroundVisibleBehind(IBinder token) {
10359        final long origId = Binder.clearCallingIdentity();
10360        try {
10361            synchronized (this) {
10362                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10363                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10364                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10365                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10366                return visible;
10367            }
10368        } finally {
10369            Binder.restoreCallingIdentity(origId);
10370        }
10371    }
10372
10373    @Override
10374    public ActivityOptions getActivityOptions(IBinder token) {
10375        final long origId = Binder.clearCallingIdentity();
10376        try {
10377            synchronized (this) {
10378                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10379                if (r != null) {
10380                    final ActivityOptions activityOptions = r.pendingOptions;
10381                    r.pendingOptions = null;
10382                    return activityOptions;
10383                }
10384                return null;
10385            }
10386        } finally {
10387            Binder.restoreCallingIdentity(origId);
10388        }
10389    }
10390
10391    @Override
10392    public void setImmersive(IBinder token, boolean immersive) {
10393        synchronized(this) {
10394            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10395            if (r == null) {
10396                throw new IllegalArgumentException();
10397            }
10398            r.immersive = immersive;
10399
10400            // update associated state if we're frontmost
10401            if (r == mFocusedActivity) {
10402                if (DEBUG_IMMERSIVE) {
10403                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10404                }
10405                applyUpdateLockStateLocked(r);
10406            }
10407        }
10408    }
10409
10410    @Override
10411    public boolean isImmersive(IBinder token) {
10412        synchronized (this) {
10413            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10414            if (r == null) {
10415                throw new IllegalArgumentException();
10416            }
10417            return r.immersive;
10418        }
10419    }
10420
10421    public boolean isTopActivityImmersive() {
10422        enforceNotIsolatedCaller("startActivity");
10423        synchronized (this) {
10424            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10425            return (r != null) ? r.immersive : false;
10426        }
10427    }
10428
10429    @Override
10430    public boolean isTopOfTask(IBinder token) {
10431        synchronized (this) {
10432            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10433            if (r == null) {
10434                throw new IllegalArgumentException();
10435            }
10436            return r.task.getTopActivity() == r;
10437        }
10438    }
10439
10440    public final void enterSafeMode() {
10441        synchronized(this) {
10442            // It only makes sense to do this before the system is ready
10443            // and started launching other packages.
10444            if (!mSystemReady) {
10445                try {
10446                    AppGlobals.getPackageManager().enterSafeMode();
10447                } catch (RemoteException e) {
10448                }
10449            }
10450
10451            mSafeMode = true;
10452        }
10453    }
10454
10455    public final void showSafeModeOverlay() {
10456        View v = LayoutInflater.from(mContext).inflate(
10457                com.android.internal.R.layout.safe_mode, null);
10458        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10459        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10460        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10461        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10462        lp.gravity = Gravity.BOTTOM | Gravity.START;
10463        lp.format = v.getBackground().getOpacity();
10464        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10465                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10466        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10467        ((WindowManager)mContext.getSystemService(
10468                Context.WINDOW_SERVICE)).addView(v, lp);
10469    }
10470
10471    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10472        if (!(sender instanceof PendingIntentRecord)) {
10473            return;
10474        }
10475        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10476        synchronized (stats) {
10477            if (mBatteryStatsService.isOnBattery()) {
10478                mBatteryStatsService.enforceCallingPermission();
10479                PendingIntentRecord rec = (PendingIntentRecord)sender;
10480                int MY_UID = Binder.getCallingUid();
10481                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10482                BatteryStatsImpl.Uid.Pkg pkg =
10483                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10484                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10485                pkg.incWakeupsLocked();
10486            }
10487        }
10488    }
10489
10490    public boolean killPids(int[] pids, String pReason, boolean secure) {
10491        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10492            throw new SecurityException("killPids only available to the system");
10493        }
10494        String reason = (pReason == null) ? "Unknown" : pReason;
10495        // XXX Note: don't acquire main activity lock here, because the window
10496        // manager calls in with its locks held.
10497
10498        boolean killed = false;
10499        synchronized (mPidsSelfLocked) {
10500            int[] types = new int[pids.length];
10501            int worstType = 0;
10502            for (int i=0; i<pids.length; i++) {
10503                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10504                if (proc != null) {
10505                    int type = proc.setAdj;
10506                    types[i] = type;
10507                    if (type > worstType) {
10508                        worstType = type;
10509                    }
10510                }
10511            }
10512
10513            // If the worst oom_adj is somewhere in the cached proc LRU range,
10514            // then constrain it so we will kill all cached procs.
10515            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10516                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10517                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10518            }
10519
10520            // If this is not a secure call, don't let it kill processes that
10521            // are important.
10522            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10523                worstType = ProcessList.SERVICE_ADJ;
10524            }
10525
10526            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10527            for (int i=0; i<pids.length; i++) {
10528                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10529                if (proc == null) {
10530                    continue;
10531                }
10532                int adj = proc.setAdj;
10533                if (adj >= worstType && !proc.killedByAm) {
10534                    proc.kill(reason, true);
10535                    killed = true;
10536                }
10537            }
10538        }
10539        return killed;
10540    }
10541
10542    @Override
10543    public void killUid(int uid, String reason) {
10544        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10545            throw new SecurityException("killUid only available to the system");
10546        }
10547        synchronized (this) {
10548            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10549                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10550                    reason != null ? reason : "kill uid");
10551        }
10552    }
10553
10554    @Override
10555    public boolean killProcessesBelowForeground(String reason) {
10556        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10557            throw new SecurityException("killProcessesBelowForeground() only available to system");
10558        }
10559
10560        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10561    }
10562
10563    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10564        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10565            throw new SecurityException("killProcessesBelowAdj() only available to system");
10566        }
10567
10568        boolean killed = false;
10569        synchronized (mPidsSelfLocked) {
10570            final int size = mPidsSelfLocked.size();
10571            for (int i = 0; i < size; i++) {
10572                final int pid = mPidsSelfLocked.keyAt(i);
10573                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10574                if (proc == null) continue;
10575
10576                final int adj = proc.setAdj;
10577                if (adj > belowAdj && !proc.killedByAm) {
10578                    proc.kill(reason, true);
10579                    killed = true;
10580                }
10581            }
10582        }
10583        return killed;
10584    }
10585
10586    @Override
10587    public void hang(final IBinder who, boolean allowRestart) {
10588        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10589                != PackageManager.PERMISSION_GRANTED) {
10590            throw new SecurityException("Requires permission "
10591                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10592        }
10593
10594        final IBinder.DeathRecipient death = new DeathRecipient() {
10595            @Override
10596            public void binderDied() {
10597                synchronized (this) {
10598                    notifyAll();
10599                }
10600            }
10601        };
10602
10603        try {
10604            who.linkToDeath(death, 0);
10605        } catch (RemoteException e) {
10606            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10607            return;
10608        }
10609
10610        synchronized (this) {
10611            Watchdog.getInstance().setAllowRestart(allowRestart);
10612            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10613            synchronized (death) {
10614                while (who.isBinderAlive()) {
10615                    try {
10616                        death.wait();
10617                    } catch (InterruptedException e) {
10618                    }
10619                }
10620            }
10621            Watchdog.getInstance().setAllowRestart(true);
10622        }
10623    }
10624
10625    @Override
10626    public void restart() {
10627        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10628                != PackageManager.PERMISSION_GRANTED) {
10629            throw new SecurityException("Requires permission "
10630                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10631        }
10632
10633        Log.i(TAG, "Sending shutdown broadcast...");
10634
10635        BroadcastReceiver br = new BroadcastReceiver() {
10636            @Override public void onReceive(Context context, Intent intent) {
10637                // Now the broadcast is done, finish up the low-level shutdown.
10638                Log.i(TAG, "Shutting down activity manager...");
10639                shutdown(10000);
10640                Log.i(TAG, "Shutdown complete, restarting!");
10641                Process.killProcess(Process.myPid());
10642                System.exit(10);
10643            }
10644        };
10645
10646        // First send the high-level shut down broadcast.
10647        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10648        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10649        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10650        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10651        mContext.sendOrderedBroadcastAsUser(intent,
10652                UserHandle.ALL, null, br, mHandler, 0, null, null);
10653        */
10654        br.onReceive(mContext, intent);
10655    }
10656
10657    private long getLowRamTimeSinceIdle(long now) {
10658        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10659    }
10660
10661    @Override
10662    public void performIdleMaintenance() {
10663        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10664                != PackageManager.PERMISSION_GRANTED) {
10665            throw new SecurityException("Requires permission "
10666                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10667        }
10668
10669        synchronized (this) {
10670            final long now = SystemClock.uptimeMillis();
10671            final long timeSinceLastIdle = now - mLastIdleTime;
10672            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10673            mLastIdleTime = now;
10674            mLowRamTimeSinceLastIdle = 0;
10675            if (mLowRamStartTime != 0) {
10676                mLowRamStartTime = now;
10677            }
10678
10679            StringBuilder sb = new StringBuilder(128);
10680            sb.append("Idle maintenance over ");
10681            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10682            sb.append(" low RAM for ");
10683            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10684            Slog.i(TAG, sb.toString());
10685
10686            // If at least 1/3 of our time since the last idle period has been spent
10687            // with RAM low, then we want to kill processes.
10688            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10689
10690            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10691                ProcessRecord proc = mLruProcesses.get(i);
10692                if (proc.notCachedSinceIdle) {
10693                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10694                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10695                        if (doKilling && proc.initialIdlePss != 0
10696                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10697                            proc.kill("idle maint (pss " + proc.lastPss
10698                                    + " from " + proc.initialIdlePss + ")", true);
10699                        }
10700                    }
10701                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10702                    proc.notCachedSinceIdle = true;
10703                    proc.initialIdlePss = 0;
10704                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10705                            isSleeping(), now);
10706                }
10707            }
10708
10709            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10710            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10711        }
10712    }
10713
10714    private void retrieveSettings() {
10715        final ContentResolver resolver = mContext.getContentResolver();
10716        String debugApp = Settings.Global.getString(
10717            resolver, Settings.Global.DEBUG_APP);
10718        boolean waitForDebugger = Settings.Global.getInt(
10719            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10720        boolean alwaysFinishActivities = Settings.Global.getInt(
10721            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10722        boolean forceRtl = Settings.Global.getInt(
10723                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10724        // Transfer any global setting for forcing RTL layout, into a System Property
10725        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10726
10727        Configuration configuration = new Configuration();
10728        Settings.System.getConfiguration(resolver, configuration);
10729        if (forceRtl) {
10730            // This will take care of setting the correct layout direction flags
10731            configuration.setLayoutDirection(configuration.locale);
10732        }
10733
10734        synchronized (this) {
10735            mDebugApp = mOrigDebugApp = debugApp;
10736            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10737            mAlwaysFinishActivities = alwaysFinishActivities;
10738            // This happens before any activities are started, so we can
10739            // change mConfiguration in-place.
10740            updateConfigurationLocked(configuration, null, false, true);
10741            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10742        }
10743    }
10744
10745    /** Loads resources after the current configuration has been set. */
10746    private void loadResourcesOnSystemReady() {
10747        final Resources res = mContext.getResources();
10748        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10749        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10750        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10751    }
10752
10753    public boolean testIsSystemReady() {
10754        // no need to synchronize(this) just to read & return the value
10755        return mSystemReady;
10756    }
10757
10758    private static File getCalledPreBootReceiversFile() {
10759        File dataDir = Environment.getDataDirectory();
10760        File systemDir = new File(dataDir, "system");
10761        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10762        return fname;
10763    }
10764
10765    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10766        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10767        File file = getCalledPreBootReceiversFile();
10768        FileInputStream fis = null;
10769        try {
10770            fis = new FileInputStream(file);
10771            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10772            int fvers = dis.readInt();
10773            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10774                String vers = dis.readUTF();
10775                String codename = dis.readUTF();
10776                String build = dis.readUTF();
10777                if (android.os.Build.VERSION.RELEASE.equals(vers)
10778                        && android.os.Build.VERSION.CODENAME.equals(codename)
10779                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10780                    int num = dis.readInt();
10781                    while (num > 0) {
10782                        num--;
10783                        String pkg = dis.readUTF();
10784                        String cls = dis.readUTF();
10785                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10786                    }
10787                }
10788            }
10789        } catch (FileNotFoundException e) {
10790        } catch (IOException e) {
10791            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10792        } finally {
10793            if (fis != null) {
10794                try {
10795                    fis.close();
10796                } catch (IOException e) {
10797                }
10798            }
10799        }
10800        return lastDoneReceivers;
10801    }
10802
10803    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10804        File file = getCalledPreBootReceiversFile();
10805        FileOutputStream fos = null;
10806        DataOutputStream dos = null;
10807        try {
10808            fos = new FileOutputStream(file);
10809            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10810            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10811            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10812            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10813            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10814            dos.writeInt(list.size());
10815            for (int i=0; i<list.size(); i++) {
10816                dos.writeUTF(list.get(i).getPackageName());
10817                dos.writeUTF(list.get(i).getClassName());
10818            }
10819        } catch (IOException e) {
10820            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10821            file.delete();
10822        } finally {
10823            FileUtils.sync(fos);
10824            if (dos != null) {
10825                try {
10826                    dos.close();
10827                } catch (IOException e) {
10828                    // TODO Auto-generated catch block
10829                    e.printStackTrace();
10830                }
10831            }
10832        }
10833    }
10834
10835    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10836            ArrayList<ComponentName> doneReceivers, int userId) {
10837        boolean waitingUpdate = false;
10838        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10839        List<ResolveInfo> ris = null;
10840        try {
10841            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10842                    intent, null, 0, userId);
10843        } catch (RemoteException e) {
10844        }
10845        if (ris != null) {
10846            for (int i=ris.size()-1; i>=0; i--) {
10847                if ((ris.get(i).activityInfo.applicationInfo.flags
10848                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10849                    ris.remove(i);
10850                }
10851            }
10852            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10853
10854            // For User 0, load the version number. When delivering to a new user, deliver
10855            // to all receivers.
10856            if (userId == UserHandle.USER_OWNER) {
10857                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10858                for (int i=0; i<ris.size(); i++) {
10859                    ActivityInfo ai = ris.get(i).activityInfo;
10860                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10861                    if (lastDoneReceivers.contains(comp)) {
10862                        // We already did the pre boot receiver for this app with the current
10863                        // platform version, so don't do it again...
10864                        ris.remove(i);
10865                        i--;
10866                        // ...however, do keep it as one that has been done, so we don't
10867                        // forget about it when rewriting the file of last done receivers.
10868                        doneReceivers.add(comp);
10869                    }
10870                }
10871            }
10872
10873            // If primary user, send broadcast to all available users, else just to userId
10874            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10875                    : new int[] { userId };
10876            for (int i = 0; i < ris.size(); i++) {
10877                ActivityInfo ai = ris.get(i).activityInfo;
10878                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10879                doneReceivers.add(comp);
10880                intent.setComponent(comp);
10881                for (int j=0; j<users.length; j++) {
10882                    IIntentReceiver finisher = null;
10883                    // On last receiver and user, set up a completion callback
10884                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10885                        finisher = new IIntentReceiver.Stub() {
10886                            public void performReceive(Intent intent, int resultCode,
10887                                    String data, Bundle extras, boolean ordered,
10888                                    boolean sticky, int sendingUser) {
10889                                // The raw IIntentReceiver interface is called
10890                                // with the AM lock held, so redispatch to
10891                                // execute our code without the lock.
10892                                mHandler.post(onFinishCallback);
10893                            }
10894                        };
10895                    }
10896                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10897                            + " for user " + users[j]);
10898                    broadcastIntentLocked(null, null, intent, null, finisher,
10899                            0, null, null, null, AppOpsManager.OP_NONE,
10900                            true, false, MY_PID, Process.SYSTEM_UID,
10901                            users[j]);
10902                    if (finisher != null) {
10903                        waitingUpdate = true;
10904                    }
10905                }
10906            }
10907        }
10908
10909        return waitingUpdate;
10910    }
10911
10912    public void systemReady(final Runnable goingCallback) {
10913        synchronized(this) {
10914            if (mSystemReady) {
10915                // If we're done calling all the receivers, run the next "boot phase" passed in
10916                // by the SystemServer
10917                if (goingCallback != null) {
10918                    goingCallback.run();
10919                }
10920                return;
10921            }
10922
10923            // Make sure we have the current profile info, since it is needed for
10924            // security checks.
10925            updateCurrentProfileIdsLocked();
10926
10927            if (mRecentTasks == null) {
10928                mRecentTasks = mTaskPersister.restoreTasksLocked();
10929                if (!mRecentTasks.isEmpty()) {
10930                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10931                }
10932                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10933                mTaskPersister.startPersisting();
10934            }
10935
10936            // Check to see if there are any update receivers to run.
10937            if (!mDidUpdate) {
10938                if (mWaitingUpdate) {
10939                    return;
10940                }
10941                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10942                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10943                    public void run() {
10944                        synchronized (ActivityManagerService.this) {
10945                            mDidUpdate = true;
10946                        }
10947                        writeLastDonePreBootReceivers(doneReceivers);
10948                        showBootMessage(mContext.getText(
10949                                R.string.android_upgrading_complete),
10950                                false);
10951                        systemReady(goingCallback);
10952                    }
10953                }, doneReceivers, UserHandle.USER_OWNER);
10954
10955                if (mWaitingUpdate) {
10956                    return;
10957                }
10958                mDidUpdate = true;
10959            }
10960
10961            mAppOpsService.systemReady();
10962            mSystemReady = true;
10963        }
10964
10965        ArrayList<ProcessRecord> procsToKill = null;
10966        synchronized(mPidsSelfLocked) {
10967            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10968                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10969                if (!isAllowedWhileBooting(proc.info)){
10970                    if (procsToKill == null) {
10971                        procsToKill = new ArrayList<ProcessRecord>();
10972                    }
10973                    procsToKill.add(proc);
10974                }
10975            }
10976        }
10977
10978        synchronized(this) {
10979            if (procsToKill != null) {
10980                for (int i=procsToKill.size()-1; i>=0; i--) {
10981                    ProcessRecord proc = procsToKill.get(i);
10982                    Slog.i(TAG, "Removing system update proc: " + proc);
10983                    removeProcessLocked(proc, true, false, "system update done");
10984                }
10985            }
10986
10987            // Now that we have cleaned up any update processes, we
10988            // are ready to start launching real processes and know that
10989            // we won't trample on them any more.
10990            mProcessesReady = true;
10991        }
10992
10993        Slog.i(TAG, "System now ready");
10994        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10995            SystemClock.uptimeMillis());
10996
10997        synchronized(this) {
10998            // Make sure we have no pre-ready processes sitting around.
10999
11000            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11001                ResolveInfo ri = mContext.getPackageManager()
11002                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
11003                                STOCK_PM_FLAGS);
11004                CharSequence errorMsg = null;
11005                if (ri != null) {
11006                    ActivityInfo ai = ri.activityInfo;
11007                    ApplicationInfo app = ai.applicationInfo;
11008                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
11009                        mTopAction = Intent.ACTION_FACTORY_TEST;
11010                        mTopData = null;
11011                        mTopComponent = new ComponentName(app.packageName,
11012                                ai.name);
11013                    } else {
11014                        errorMsg = mContext.getResources().getText(
11015                                com.android.internal.R.string.factorytest_not_system);
11016                    }
11017                } else {
11018                    errorMsg = mContext.getResources().getText(
11019                            com.android.internal.R.string.factorytest_no_action);
11020                }
11021                if (errorMsg != null) {
11022                    mTopAction = null;
11023                    mTopData = null;
11024                    mTopComponent = null;
11025                    Message msg = Message.obtain();
11026                    msg.what = SHOW_FACTORY_ERROR_MSG;
11027                    msg.getData().putCharSequence("msg", errorMsg);
11028                    mHandler.sendMessage(msg);
11029                }
11030            }
11031        }
11032
11033        retrieveSettings();
11034        loadResourcesOnSystemReady();
11035
11036        synchronized (this) {
11037            readGrantedUriPermissionsLocked();
11038        }
11039
11040        if (goingCallback != null) goingCallback.run();
11041
11042        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11043                Integer.toString(mCurrentUserId), mCurrentUserId);
11044        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11045                Integer.toString(mCurrentUserId), mCurrentUserId);
11046        mSystemServiceManager.startUser(mCurrentUserId);
11047
11048        synchronized (this) {
11049            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11050                try {
11051                    List apps = AppGlobals.getPackageManager().
11052                        getPersistentApplications(STOCK_PM_FLAGS);
11053                    if (apps != null) {
11054                        int N = apps.size();
11055                        int i;
11056                        for (i=0; i<N; i++) {
11057                            ApplicationInfo info
11058                                = (ApplicationInfo)apps.get(i);
11059                            if (info != null &&
11060                                    !info.packageName.equals("android")) {
11061                                addAppLocked(info, false, null /* ABI override */);
11062                            }
11063                        }
11064                    }
11065                } catch (RemoteException ex) {
11066                    // pm is in same process, this will never happen.
11067                }
11068            }
11069
11070            // Start up initial activity.
11071            mBooting = true;
11072
11073            try {
11074                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11075                    Message msg = Message.obtain();
11076                    msg.what = SHOW_UID_ERROR_MSG;
11077                    mHandler.sendMessage(msg);
11078                }
11079            } catch (RemoteException e) {
11080            }
11081
11082            long ident = Binder.clearCallingIdentity();
11083            try {
11084                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11085                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11086                        | Intent.FLAG_RECEIVER_FOREGROUND);
11087                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11088                broadcastIntentLocked(null, null, intent,
11089                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11090                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11091                intent = new Intent(Intent.ACTION_USER_STARTING);
11092                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11093                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11094                broadcastIntentLocked(null, null, intent,
11095                        null, new IIntentReceiver.Stub() {
11096                            @Override
11097                            public void performReceive(Intent intent, int resultCode, String data,
11098                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11099                                    throws RemoteException {
11100                            }
11101                        }, 0, null, null,
11102                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11103                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11104            } catch (Throwable t) {
11105                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11106            } finally {
11107                Binder.restoreCallingIdentity(ident);
11108            }
11109            mStackSupervisor.resumeTopActivitiesLocked();
11110            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11111        }
11112    }
11113
11114    private boolean makeAppCrashingLocked(ProcessRecord app,
11115            String shortMsg, String longMsg, String stackTrace) {
11116        app.crashing = true;
11117        app.crashingReport = generateProcessError(app,
11118                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11119        startAppProblemLocked(app);
11120        app.stopFreezingAllLocked();
11121        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11122    }
11123
11124    private void makeAppNotRespondingLocked(ProcessRecord app,
11125            String activity, String shortMsg, String longMsg) {
11126        app.notResponding = true;
11127        app.notRespondingReport = generateProcessError(app,
11128                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11129                activity, shortMsg, longMsg, null);
11130        startAppProblemLocked(app);
11131        app.stopFreezingAllLocked();
11132    }
11133
11134    /**
11135     * Generate a process error record, suitable for attachment to a ProcessRecord.
11136     *
11137     * @param app The ProcessRecord in which the error occurred.
11138     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11139     *                      ActivityManager.AppErrorStateInfo
11140     * @param activity The activity associated with the crash, if known.
11141     * @param shortMsg Short message describing the crash.
11142     * @param longMsg Long message describing the crash.
11143     * @param stackTrace Full crash stack trace, may be null.
11144     *
11145     * @return Returns a fully-formed AppErrorStateInfo record.
11146     */
11147    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11148            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11149        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11150
11151        report.condition = condition;
11152        report.processName = app.processName;
11153        report.pid = app.pid;
11154        report.uid = app.info.uid;
11155        report.tag = activity;
11156        report.shortMsg = shortMsg;
11157        report.longMsg = longMsg;
11158        report.stackTrace = stackTrace;
11159
11160        return report;
11161    }
11162
11163    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11164        synchronized (this) {
11165            app.crashing = false;
11166            app.crashingReport = null;
11167            app.notResponding = false;
11168            app.notRespondingReport = null;
11169            if (app.anrDialog == fromDialog) {
11170                app.anrDialog = null;
11171            }
11172            if (app.waitDialog == fromDialog) {
11173                app.waitDialog = null;
11174            }
11175            if (app.pid > 0 && app.pid != MY_PID) {
11176                handleAppCrashLocked(app, null, null, null);
11177                app.kill("user request after error", true);
11178            }
11179        }
11180    }
11181
11182    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11183            String stackTrace) {
11184        long now = SystemClock.uptimeMillis();
11185
11186        Long crashTime;
11187        if (!app.isolated) {
11188            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11189        } else {
11190            crashTime = null;
11191        }
11192        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11193            // This process loses!
11194            Slog.w(TAG, "Process " + app.info.processName
11195                    + " has crashed too many times: killing!");
11196            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11197                    app.userId, app.info.processName, app.uid);
11198            mStackSupervisor.handleAppCrashLocked(app);
11199            if (!app.persistent) {
11200                // We don't want to start this process again until the user
11201                // explicitly does so...  but for persistent process, we really
11202                // need to keep it running.  If a persistent process is actually
11203                // repeatedly crashing, then badness for everyone.
11204                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11205                        app.info.processName);
11206                if (!app.isolated) {
11207                    // XXX We don't have a way to mark isolated processes
11208                    // as bad, since they don't have a peristent identity.
11209                    mBadProcesses.put(app.info.processName, app.uid,
11210                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11211                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11212                }
11213                app.bad = true;
11214                app.removed = true;
11215                // Don't let services in this process be restarted and potentially
11216                // annoy the user repeatedly.  Unless it is persistent, since those
11217                // processes run critical code.
11218                removeProcessLocked(app, false, false, "crash");
11219                mStackSupervisor.resumeTopActivitiesLocked();
11220                return false;
11221            }
11222            mStackSupervisor.resumeTopActivitiesLocked();
11223        } else {
11224            mStackSupervisor.finishTopRunningActivityLocked(app);
11225        }
11226
11227        // Bump up the crash count of any services currently running in the proc.
11228        for (int i=app.services.size()-1; i>=0; i--) {
11229            // Any services running in the application need to be placed
11230            // back in the pending list.
11231            ServiceRecord sr = app.services.valueAt(i);
11232            sr.crashCount++;
11233        }
11234
11235        // If the crashing process is what we consider to be the "home process" and it has been
11236        // replaced by a third-party app, clear the package preferred activities from packages
11237        // with a home activity running in the process to prevent a repeatedly crashing app
11238        // from blocking the user to manually clear the list.
11239        final ArrayList<ActivityRecord> activities = app.activities;
11240        if (app == mHomeProcess && activities.size() > 0
11241                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11242            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11243                final ActivityRecord r = activities.get(activityNdx);
11244                if (r.isHomeActivity()) {
11245                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11246                    try {
11247                        ActivityThread.getPackageManager()
11248                                .clearPackagePreferredActivities(r.packageName);
11249                    } catch (RemoteException c) {
11250                        // pm is in same process, this will never happen.
11251                    }
11252                }
11253            }
11254        }
11255
11256        if (!app.isolated) {
11257            // XXX Can't keep track of crash times for isolated processes,
11258            // because they don't have a perisistent identity.
11259            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11260        }
11261
11262        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11263        return true;
11264    }
11265
11266    void startAppProblemLocked(ProcessRecord app) {
11267        // If this app is not running under the current user, then we
11268        // can't give it a report button because that would require
11269        // launching the report UI under a different user.
11270        app.errorReportReceiver = null;
11271
11272        for (int userId : mCurrentProfileIds) {
11273            if (app.userId == userId) {
11274                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11275                        mContext, app.info.packageName, app.info.flags);
11276            }
11277        }
11278        skipCurrentReceiverLocked(app);
11279    }
11280
11281    void skipCurrentReceiverLocked(ProcessRecord app) {
11282        for (BroadcastQueue queue : mBroadcastQueues) {
11283            queue.skipCurrentReceiverLocked(app);
11284        }
11285    }
11286
11287    /**
11288     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11289     * The application process will exit immediately after this call returns.
11290     * @param app object of the crashing app, null for the system server
11291     * @param crashInfo describing the exception
11292     */
11293    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11294        ProcessRecord r = findAppProcess(app, "Crash");
11295        final String processName = app == null ? "system_server"
11296                : (r == null ? "unknown" : r.processName);
11297
11298        handleApplicationCrashInner("crash", r, processName, crashInfo);
11299    }
11300
11301    /* Native crash reporting uses this inner version because it needs to be somewhat
11302     * decoupled from the AM-managed cleanup lifecycle
11303     */
11304    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11305            ApplicationErrorReport.CrashInfo crashInfo) {
11306        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11307                UserHandle.getUserId(Binder.getCallingUid()), processName,
11308                r == null ? -1 : r.info.flags,
11309                crashInfo.exceptionClassName,
11310                crashInfo.exceptionMessage,
11311                crashInfo.throwFileName,
11312                crashInfo.throwLineNumber);
11313
11314        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11315
11316        crashApplication(r, crashInfo);
11317    }
11318
11319    public void handleApplicationStrictModeViolation(
11320            IBinder app,
11321            int violationMask,
11322            StrictMode.ViolationInfo info) {
11323        ProcessRecord r = findAppProcess(app, "StrictMode");
11324        if (r == null) {
11325            return;
11326        }
11327
11328        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11329            Integer stackFingerprint = info.hashCode();
11330            boolean logIt = true;
11331            synchronized (mAlreadyLoggedViolatedStacks) {
11332                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11333                    logIt = false;
11334                    // TODO: sub-sample into EventLog for these, with
11335                    // the info.durationMillis?  Then we'd get
11336                    // the relative pain numbers, without logging all
11337                    // the stack traces repeatedly.  We'd want to do
11338                    // likewise in the client code, which also does
11339                    // dup suppression, before the Binder call.
11340                } else {
11341                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11342                        mAlreadyLoggedViolatedStacks.clear();
11343                    }
11344                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11345                }
11346            }
11347            if (logIt) {
11348                logStrictModeViolationToDropBox(r, info);
11349            }
11350        }
11351
11352        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11353            AppErrorResult result = new AppErrorResult();
11354            synchronized (this) {
11355                final long origId = Binder.clearCallingIdentity();
11356
11357                Message msg = Message.obtain();
11358                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11359                HashMap<String, Object> data = new HashMap<String, Object>();
11360                data.put("result", result);
11361                data.put("app", r);
11362                data.put("violationMask", violationMask);
11363                data.put("info", info);
11364                msg.obj = data;
11365                mHandler.sendMessage(msg);
11366
11367                Binder.restoreCallingIdentity(origId);
11368            }
11369            int res = result.get();
11370            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11371        }
11372    }
11373
11374    // Depending on the policy in effect, there could be a bunch of
11375    // these in quick succession so we try to batch these together to
11376    // minimize disk writes, number of dropbox entries, and maximize
11377    // compression, by having more fewer, larger records.
11378    private void logStrictModeViolationToDropBox(
11379            ProcessRecord process,
11380            StrictMode.ViolationInfo info) {
11381        if (info == null) {
11382            return;
11383        }
11384        final boolean isSystemApp = process == null ||
11385                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11386                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11387        final String processName = process == null ? "unknown" : process.processName;
11388        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11389        final DropBoxManager dbox = (DropBoxManager)
11390                mContext.getSystemService(Context.DROPBOX_SERVICE);
11391
11392        // Exit early if the dropbox isn't configured to accept this report type.
11393        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11394
11395        boolean bufferWasEmpty;
11396        boolean needsFlush;
11397        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11398        synchronized (sb) {
11399            bufferWasEmpty = sb.length() == 0;
11400            appendDropBoxProcessHeaders(process, processName, sb);
11401            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11402            sb.append("System-App: ").append(isSystemApp).append("\n");
11403            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11404            if (info.violationNumThisLoop != 0) {
11405                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11406            }
11407            if (info.numAnimationsRunning != 0) {
11408                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11409            }
11410            if (info.broadcastIntentAction != null) {
11411                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11412            }
11413            if (info.durationMillis != -1) {
11414                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11415            }
11416            if (info.numInstances != -1) {
11417                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11418            }
11419            if (info.tags != null) {
11420                for (String tag : info.tags) {
11421                    sb.append("Span-Tag: ").append(tag).append("\n");
11422                }
11423            }
11424            sb.append("\n");
11425            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11426                sb.append(info.crashInfo.stackTrace);
11427            }
11428            sb.append("\n");
11429
11430            // Only buffer up to ~64k.  Various logging bits truncate
11431            // things at 128k.
11432            needsFlush = (sb.length() > 64 * 1024);
11433        }
11434
11435        // Flush immediately if the buffer's grown too large, or this
11436        // is a non-system app.  Non-system apps are isolated with a
11437        // different tag & policy and not batched.
11438        //
11439        // Batching is useful during internal testing with
11440        // StrictMode settings turned up high.  Without batching,
11441        // thousands of separate files could be created on boot.
11442        if (!isSystemApp || needsFlush) {
11443            new Thread("Error dump: " + dropboxTag) {
11444                @Override
11445                public void run() {
11446                    String report;
11447                    synchronized (sb) {
11448                        report = sb.toString();
11449                        sb.delete(0, sb.length());
11450                        sb.trimToSize();
11451                    }
11452                    if (report.length() != 0) {
11453                        dbox.addText(dropboxTag, report);
11454                    }
11455                }
11456            }.start();
11457            return;
11458        }
11459
11460        // System app batching:
11461        if (!bufferWasEmpty) {
11462            // An existing dropbox-writing thread is outstanding, so
11463            // we don't need to start it up.  The existing thread will
11464            // catch the buffer appends we just did.
11465            return;
11466        }
11467
11468        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11469        // (After this point, we shouldn't access AMS internal data structures.)
11470        new Thread("Error dump: " + dropboxTag) {
11471            @Override
11472            public void run() {
11473                // 5 second sleep to let stacks arrive and be batched together
11474                try {
11475                    Thread.sleep(5000);  // 5 seconds
11476                } catch (InterruptedException e) {}
11477
11478                String errorReport;
11479                synchronized (mStrictModeBuffer) {
11480                    errorReport = mStrictModeBuffer.toString();
11481                    if (errorReport.length() == 0) {
11482                        return;
11483                    }
11484                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11485                    mStrictModeBuffer.trimToSize();
11486                }
11487                dbox.addText(dropboxTag, errorReport);
11488            }
11489        }.start();
11490    }
11491
11492    /**
11493     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11494     * @param app object of the crashing app, null for the system server
11495     * @param tag reported by the caller
11496     * @param system whether this wtf is coming from the system
11497     * @param crashInfo describing the context of the error
11498     * @return true if the process should exit immediately (WTF is fatal)
11499     */
11500    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11501            final ApplicationErrorReport.CrashInfo crashInfo) {
11502        final ProcessRecord r = findAppProcess(app, "WTF");
11503        final String processName = app == null ? "system_server"
11504                : (r == null ? "unknown" : r.processName);
11505
11506        EventLog.writeEvent(EventLogTags.AM_WTF,
11507                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11508                processName,
11509                r == null ? -1 : r.info.flags,
11510                tag, crashInfo.exceptionMessage);
11511
11512        if (system) {
11513            // If this is coming from the system, we could very well have low-level
11514            // system locks held, so we want to do this all asynchronously.  And we
11515            // never want this to become fatal, so there is that too.
11516            mHandler.post(new Runnable() {
11517                @Override public void run() {
11518                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11519                            crashInfo);
11520                }
11521            });
11522            return false;
11523        }
11524
11525        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11526
11527        if (r != null && r.pid != Process.myPid() &&
11528                Settings.Global.getInt(mContext.getContentResolver(),
11529                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11530            crashApplication(r, crashInfo);
11531            return true;
11532        } else {
11533            return false;
11534        }
11535    }
11536
11537    /**
11538     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11539     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11540     */
11541    private ProcessRecord findAppProcess(IBinder app, String reason) {
11542        if (app == null) {
11543            return null;
11544        }
11545
11546        synchronized (this) {
11547            final int NP = mProcessNames.getMap().size();
11548            for (int ip=0; ip<NP; ip++) {
11549                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11550                final int NA = apps.size();
11551                for (int ia=0; ia<NA; ia++) {
11552                    ProcessRecord p = apps.valueAt(ia);
11553                    if (p.thread != null && p.thread.asBinder() == app) {
11554                        return p;
11555                    }
11556                }
11557            }
11558
11559            Slog.w(TAG, "Can't find mystery application for " + reason
11560                    + " from pid=" + Binder.getCallingPid()
11561                    + " uid=" + Binder.getCallingUid() + ": " + app);
11562            return null;
11563        }
11564    }
11565
11566    /**
11567     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11568     * to append various headers to the dropbox log text.
11569     */
11570    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11571            StringBuilder sb) {
11572        // Watchdog thread ends up invoking this function (with
11573        // a null ProcessRecord) to add the stack file to dropbox.
11574        // Do not acquire a lock on this (am) in such cases, as it
11575        // could cause a potential deadlock, if and when watchdog
11576        // is invoked due to unavailability of lock on am and it
11577        // would prevent watchdog from killing system_server.
11578        if (process == null) {
11579            sb.append("Process: ").append(processName).append("\n");
11580            return;
11581        }
11582        // Note: ProcessRecord 'process' is guarded by the service
11583        // instance.  (notably process.pkgList, which could otherwise change
11584        // concurrently during execution of this method)
11585        synchronized (this) {
11586            sb.append("Process: ").append(processName).append("\n");
11587            int flags = process.info.flags;
11588            IPackageManager pm = AppGlobals.getPackageManager();
11589            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11590            for (int ip=0; ip<process.pkgList.size(); ip++) {
11591                String pkg = process.pkgList.keyAt(ip);
11592                sb.append("Package: ").append(pkg);
11593                try {
11594                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11595                    if (pi != null) {
11596                        sb.append(" v").append(pi.versionCode);
11597                        if (pi.versionName != null) {
11598                            sb.append(" (").append(pi.versionName).append(")");
11599                        }
11600                    }
11601                } catch (RemoteException e) {
11602                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11603                }
11604                sb.append("\n");
11605            }
11606        }
11607    }
11608
11609    private static String processClass(ProcessRecord process) {
11610        if (process == null || process.pid == MY_PID) {
11611            return "system_server";
11612        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11613            return "system_app";
11614        } else {
11615            return "data_app";
11616        }
11617    }
11618
11619    /**
11620     * Write a description of an error (crash, WTF, ANR) to the drop box.
11621     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11622     * @param process which caused the error, null means the system server
11623     * @param activity which triggered the error, null if unknown
11624     * @param parent activity related to the error, null if unknown
11625     * @param subject line related to the error, null if absent
11626     * @param report in long form describing the error, null if absent
11627     * @param logFile to include in the report, null if none
11628     * @param crashInfo giving an application stack trace, null if absent
11629     */
11630    public void addErrorToDropBox(String eventType,
11631            ProcessRecord process, String processName, ActivityRecord activity,
11632            ActivityRecord parent, String subject,
11633            final String report, final File logFile,
11634            final ApplicationErrorReport.CrashInfo crashInfo) {
11635        // NOTE -- this must never acquire the ActivityManagerService lock,
11636        // otherwise the watchdog may be prevented from resetting the system.
11637
11638        final String dropboxTag = processClass(process) + "_" + eventType;
11639        final DropBoxManager dbox = (DropBoxManager)
11640                mContext.getSystemService(Context.DROPBOX_SERVICE);
11641
11642        // Exit early if the dropbox isn't configured to accept this report type.
11643        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11644
11645        final StringBuilder sb = new StringBuilder(1024);
11646        appendDropBoxProcessHeaders(process, processName, sb);
11647        if (activity != null) {
11648            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11649        }
11650        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11651            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11652        }
11653        if (parent != null && parent != activity) {
11654            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11655        }
11656        if (subject != null) {
11657            sb.append("Subject: ").append(subject).append("\n");
11658        }
11659        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11660        if (Debug.isDebuggerConnected()) {
11661            sb.append("Debugger: Connected\n");
11662        }
11663        sb.append("\n");
11664
11665        // Do the rest in a worker thread to avoid blocking the caller on I/O
11666        // (After this point, we shouldn't access AMS internal data structures.)
11667        Thread worker = new Thread("Error dump: " + dropboxTag) {
11668            @Override
11669            public void run() {
11670                if (report != null) {
11671                    sb.append(report);
11672                }
11673                if (logFile != null) {
11674                    try {
11675                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11676                                    "\n\n[[TRUNCATED]]"));
11677                    } catch (IOException e) {
11678                        Slog.e(TAG, "Error reading " + logFile, e);
11679                    }
11680                }
11681                if (crashInfo != null && crashInfo.stackTrace != null) {
11682                    sb.append(crashInfo.stackTrace);
11683                }
11684
11685                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11686                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11687                if (lines > 0) {
11688                    sb.append("\n");
11689
11690                    // Merge several logcat streams, and take the last N lines
11691                    InputStreamReader input = null;
11692                    try {
11693                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11694                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11695                                "-b", "crash",
11696                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11697
11698                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11699                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11700                        input = new InputStreamReader(logcat.getInputStream());
11701
11702                        int num;
11703                        char[] buf = new char[8192];
11704                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11705                    } catch (IOException e) {
11706                        Slog.e(TAG, "Error running logcat", e);
11707                    } finally {
11708                        if (input != null) try { input.close(); } catch (IOException e) {}
11709                    }
11710                }
11711
11712                dbox.addText(dropboxTag, sb.toString());
11713            }
11714        };
11715
11716        if (process == null) {
11717            // If process is null, we are being called from some internal code
11718            // and may be about to die -- run this synchronously.
11719            worker.run();
11720        } else {
11721            worker.start();
11722        }
11723    }
11724
11725    /**
11726     * Bring up the "unexpected error" dialog box for a crashing app.
11727     * Deal with edge cases (intercepts from instrumented applications,
11728     * ActivityController, error intent receivers, that sort of thing).
11729     * @param r the application crashing
11730     * @param crashInfo describing the failure
11731     */
11732    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11733        long timeMillis = System.currentTimeMillis();
11734        String shortMsg = crashInfo.exceptionClassName;
11735        String longMsg = crashInfo.exceptionMessage;
11736        String stackTrace = crashInfo.stackTrace;
11737        if (shortMsg != null && longMsg != null) {
11738            longMsg = shortMsg + ": " + longMsg;
11739        } else if (shortMsg != null) {
11740            longMsg = shortMsg;
11741        }
11742
11743        AppErrorResult result = new AppErrorResult();
11744        synchronized (this) {
11745            if (mController != null) {
11746                try {
11747                    String name = r != null ? r.processName : null;
11748                    int pid = r != null ? r.pid : Binder.getCallingPid();
11749                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11750                    if (!mController.appCrashed(name, pid,
11751                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11752                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11753                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11754                            Slog.w(TAG, "Skip killing native crashed app " + name
11755                                    + "(" + pid + ") during testing");
11756                        } else {
11757                            Slog.w(TAG, "Force-killing crashed app " + name
11758                                    + " at watcher's request");
11759                            if (r != null) {
11760                                r.kill("crash", true);
11761                            } else {
11762                                // Huh.
11763                                Process.killProcess(pid);
11764                                Process.killProcessGroup(uid, pid);
11765                            }
11766                        }
11767                        return;
11768                    }
11769                } catch (RemoteException e) {
11770                    mController = null;
11771                    Watchdog.getInstance().setActivityController(null);
11772                }
11773            }
11774
11775            final long origId = Binder.clearCallingIdentity();
11776
11777            // If this process is running instrumentation, finish it.
11778            if (r != null && r.instrumentationClass != null) {
11779                Slog.w(TAG, "Error in app " + r.processName
11780                      + " running instrumentation " + r.instrumentationClass + ":");
11781                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11782                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11783                Bundle info = new Bundle();
11784                info.putString("shortMsg", shortMsg);
11785                info.putString("longMsg", longMsg);
11786                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11787                Binder.restoreCallingIdentity(origId);
11788                return;
11789            }
11790
11791            // If we can't identify the process or it's already exceeded its crash quota,
11792            // quit right away without showing a crash dialog.
11793            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11794                Binder.restoreCallingIdentity(origId);
11795                return;
11796            }
11797
11798            Message msg = Message.obtain();
11799            msg.what = SHOW_ERROR_MSG;
11800            HashMap data = new HashMap();
11801            data.put("result", result);
11802            data.put("app", r);
11803            msg.obj = data;
11804            mHandler.sendMessage(msg);
11805
11806            Binder.restoreCallingIdentity(origId);
11807        }
11808
11809        int res = result.get();
11810
11811        Intent appErrorIntent = null;
11812        synchronized (this) {
11813            if (r != null && !r.isolated) {
11814                // XXX Can't keep track of crash time for isolated processes,
11815                // since they don't have a persistent identity.
11816                mProcessCrashTimes.put(r.info.processName, r.uid,
11817                        SystemClock.uptimeMillis());
11818            }
11819            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11820                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11821            }
11822        }
11823
11824        if (appErrorIntent != null) {
11825            try {
11826                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11827            } catch (ActivityNotFoundException e) {
11828                Slog.w(TAG, "bug report receiver dissappeared", e);
11829            }
11830        }
11831    }
11832
11833    Intent createAppErrorIntentLocked(ProcessRecord r,
11834            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11835        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11836        if (report == null) {
11837            return null;
11838        }
11839        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11840        result.setComponent(r.errorReportReceiver);
11841        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11842        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11843        return result;
11844    }
11845
11846    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11847            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11848        if (r.errorReportReceiver == null) {
11849            return null;
11850        }
11851
11852        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11853            return null;
11854        }
11855
11856        ApplicationErrorReport report = new ApplicationErrorReport();
11857        report.packageName = r.info.packageName;
11858        report.installerPackageName = r.errorReportReceiver.getPackageName();
11859        report.processName = r.processName;
11860        report.time = timeMillis;
11861        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11862
11863        if (r.crashing || r.forceCrashReport) {
11864            report.type = ApplicationErrorReport.TYPE_CRASH;
11865            report.crashInfo = crashInfo;
11866        } else if (r.notResponding) {
11867            report.type = ApplicationErrorReport.TYPE_ANR;
11868            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11869
11870            report.anrInfo.activity = r.notRespondingReport.tag;
11871            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11872            report.anrInfo.info = r.notRespondingReport.longMsg;
11873        }
11874
11875        return report;
11876    }
11877
11878    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11879        enforceNotIsolatedCaller("getProcessesInErrorState");
11880        // assume our apps are happy - lazy create the list
11881        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11882
11883        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11884                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11885        int userId = UserHandle.getUserId(Binder.getCallingUid());
11886
11887        synchronized (this) {
11888
11889            // iterate across all processes
11890            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11891                ProcessRecord app = mLruProcesses.get(i);
11892                if (!allUsers && app.userId != userId) {
11893                    continue;
11894                }
11895                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11896                    // This one's in trouble, so we'll generate a report for it
11897                    // crashes are higher priority (in case there's a crash *and* an anr)
11898                    ActivityManager.ProcessErrorStateInfo report = null;
11899                    if (app.crashing) {
11900                        report = app.crashingReport;
11901                    } else if (app.notResponding) {
11902                        report = app.notRespondingReport;
11903                    }
11904
11905                    if (report != null) {
11906                        if (errList == null) {
11907                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11908                        }
11909                        errList.add(report);
11910                    } else {
11911                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11912                                " crashing = " + app.crashing +
11913                                " notResponding = " + app.notResponding);
11914                    }
11915                }
11916            }
11917        }
11918
11919        return errList;
11920    }
11921
11922    static int procStateToImportance(int procState, int memAdj,
11923            ActivityManager.RunningAppProcessInfo currApp) {
11924        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11925        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11926            currApp.lru = memAdj;
11927        } else {
11928            currApp.lru = 0;
11929        }
11930        return imp;
11931    }
11932
11933    private void fillInProcMemInfo(ProcessRecord app,
11934            ActivityManager.RunningAppProcessInfo outInfo) {
11935        outInfo.pid = app.pid;
11936        outInfo.uid = app.info.uid;
11937        if (mHeavyWeightProcess == app) {
11938            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11939        }
11940        if (app.persistent) {
11941            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11942        }
11943        if (app.activities.size() > 0) {
11944            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11945        }
11946        outInfo.lastTrimLevel = app.trimMemoryLevel;
11947        int adj = app.curAdj;
11948        int procState = app.curProcState;
11949        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11950        outInfo.importanceReasonCode = app.adjTypeCode;
11951        outInfo.processState = app.curProcState;
11952    }
11953
11954    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11955        enforceNotIsolatedCaller("getRunningAppProcesses");
11956        // Lazy instantiation of list
11957        List<ActivityManager.RunningAppProcessInfo> runList = null;
11958        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11959                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11960        int userId = UserHandle.getUserId(Binder.getCallingUid());
11961        synchronized (this) {
11962            // Iterate across all processes
11963            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11964                ProcessRecord app = mLruProcesses.get(i);
11965                if (!allUsers && app.userId != userId) {
11966                    continue;
11967                }
11968                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11969                    // Generate process state info for running application
11970                    ActivityManager.RunningAppProcessInfo currApp =
11971                        new ActivityManager.RunningAppProcessInfo(app.processName,
11972                                app.pid, app.getPackageList());
11973                    fillInProcMemInfo(app, currApp);
11974                    if (app.adjSource instanceof ProcessRecord) {
11975                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11976                        currApp.importanceReasonImportance =
11977                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11978                                        app.adjSourceProcState);
11979                    } else if (app.adjSource instanceof ActivityRecord) {
11980                        ActivityRecord r = (ActivityRecord)app.adjSource;
11981                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11982                    }
11983                    if (app.adjTarget instanceof ComponentName) {
11984                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11985                    }
11986                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11987                    //        + " lru=" + currApp.lru);
11988                    if (runList == null) {
11989                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11990                    }
11991                    runList.add(currApp);
11992                }
11993            }
11994        }
11995        return runList;
11996    }
11997
11998    public List<ApplicationInfo> getRunningExternalApplications() {
11999        enforceNotIsolatedCaller("getRunningExternalApplications");
12000        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
12001        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
12002        if (runningApps != null && runningApps.size() > 0) {
12003            Set<String> extList = new HashSet<String>();
12004            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
12005                if (app.pkgList != null) {
12006                    for (String pkg : app.pkgList) {
12007                        extList.add(pkg);
12008                    }
12009                }
12010            }
12011            IPackageManager pm = AppGlobals.getPackageManager();
12012            for (String pkg : extList) {
12013                try {
12014                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
12015                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
12016                        retList.add(info);
12017                    }
12018                } catch (RemoteException e) {
12019                }
12020            }
12021        }
12022        return retList;
12023    }
12024
12025    @Override
12026    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12027        enforceNotIsolatedCaller("getMyMemoryState");
12028        synchronized (this) {
12029            ProcessRecord proc;
12030            synchronized (mPidsSelfLocked) {
12031                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12032            }
12033            fillInProcMemInfo(proc, outInfo);
12034        }
12035    }
12036
12037    @Override
12038    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12039        if (checkCallingPermission(android.Manifest.permission.DUMP)
12040                != PackageManager.PERMISSION_GRANTED) {
12041            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12042                    + Binder.getCallingPid()
12043                    + ", uid=" + Binder.getCallingUid()
12044                    + " without permission "
12045                    + android.Manifest.permission.DUMP);
12046            return;
12047        }
12048
12049        boolean dumpAll = false;
12050        boolean dumpClient = false;
12051        String dumpPackage = null;
12052
12053        int opti = 0;
12054        while (opti < args.length) {
12055            String opt = args[opti];
12056            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12057                break;
12058            }
12059            opti++;
12060            if ("-a".equals(opt)) {
12061                dumpAll = true;
12062            } else if ("-c".equals(opt)) {
12063                dumpClient = true;
12064            } else if ("-h".equals(opt)) {
12065                pw.println("Activity manager dump options:");
12066                pw.println("  [-a] [-c] [-h] [cmd] ...");
12067                pw.println("  cmd may be one of:");
12068                pw.println("    a[ctivities]: activity stack state");
12069                pw.println("    r[recents]: recent activities state");
12070                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12071                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12072                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12073                pw.println("    o[om]: out of memory management");
12074                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12075                pw.println("    provider [COMP_SPEC]: provider client-side state");
12076                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12077                pw.println("    service [COMP_SPEC]: service client-side state");
12078                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12079                pw.println("    all: dump all activities");
12080                pw.println("    top: dump the top activity");
12081                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12082                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12083                pw.println("    a partial substring in a component name, a");
12084                pw.println("    hex object identifier.");
12085                pw.println("  -a: include all available server state.");
12086                pw.println("  -c: include client state.");
12087                return;
12088            } else {
12089                pw.println("Unknown argument: " + opt + "; use -h for help");
12090            }
12091        }
12092
12093        long origId = Binder.clearCallingIdentity();
12094        boolean more = false;
12095        // Is the caller requesting to dump a particular piece of data?
12096        if (opti < args.length) {
12097            String cmd = args[opti];
12098            opti++;
12099            if ("activities".equals(cmd) || "a".equals(cmd)) {
12100                synchronized (this) {
12101                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12102                }
12103            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12104                synchronized (this) {
12105                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12106                }
12107            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12108                String[] newArgs;
12109                String name;
12110                if (opti >= args.length) {
12111                    name = null;
12112                    newArgs = EMPTY_STRING_ARRAY;
12113                } else {
12114                    name = args[opti];
12115                    opti++;
12116                    newArgs = new String[args.length - opti];
12117                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12118                            args.length - opti);
12119                }
12120                synchronized (this) {
12121                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12122                }
12123            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12124                String[] newArgs;
12125                String name;
12126                if (opti >= args.length) {
12127                    name = null;
12128                    newArgs = EMPTY_STRING_ARRAY;
12129                } else {
12130                    name = args[opti];
12131                    opti++;
12132                    newArgs = new String[args.length - opti];
12133                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12134                            args.length - opti);
12135                }
12136                synchronized (this) {
12137                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12138                }
12139            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12140                String[] newArgs;
12141                String name;
12142                if (opti >= args.length) {
12143                    name = null;
12144                    newArgs = EMPTY_STRING_ARRAY;
12145                } else {
12146                    name = args[opti];
12147                    opti++;
12148                    newArgs = new String[args.length - opti];
12149                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12150                            args.length - opti);
12151                }
12152                synchronized (this) {
12153                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12154                }
12155            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12156                synchronized (this) {
12157                    dumpOomLocked(fd, pw, args, opti, true);
12158                }
12159            } else if ("provider".equals(cmd)) {
12160                String[] newArgs;
12161                String name;
12162                if (opti >= args.length) {
12163                    name = null;
12164                    newArgs = EMPTY_STRING_ARRAY;
12165                } else {
12166                    name = args[opti];
12167                    opti++;
12168                    newArgs = new String[args.length - opti];
12169                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12170                }
12171                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12172                    pw.println("No providers match: " + name);
12173                    pw.println("Use -h for help.");
12174                }
12175            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12176                synchronized (this) {
12177                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12178                }
12179            } else if ("service".equals(cmd)) {
12180                String[] newArgs;
12181                String name;
12182                if (opti >= args.length) {
12183                    name = null;
12184                    newArgs = EMPTY_STRING_ARRAY;
12185                } else {
12186                    name = args[opti];
12187                    opti++;
12188                    newArgs = new String[args.length - opti];
12189                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12190                            args.length - opti);
12191                }
12192                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12193                    pw.println("No services match: " + name);
12194                    pw.println("Use -h for help.");
12195                }
12196            } else if ("package".equals(cmd)) {
12197                String[] newArgs;
12198                if (opti >= args.length) {
12199                    pw.println("package: no package name specified");
12200                    pw.println("Use -h for help.");
12201                } else {
12202                    dumpPackage = args[opti];
12203                    opti++;
12204                    newArgs = new String[args.length - opti];
12205                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12206                            args.length - opti);
12207                    args = newArgs;
12208                    opti = 0;
12209                    more = true;
12210                }
12211            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12212                synchronized (this) {
12213                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12214                }
12215            } else {
12216                // Dumping a single activity?
12217                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12218                    pw.println("Bad activity command, or no activities match: " + cmd);
12219                    pw.println("Use -h for help.");
12220                }
12221            }
12222            if (!more) {
12223                Binder.restoreCallingIdentity(origId);
12224                return;
12225            }
12226        }
12227
12228        // No piece of data specified, dump everything.
12229        synchronized (this) {
12230            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12231            pw.println();
12232            if (dumpAll) {
12233                pw.println("-------------------------------------------------------------------------------");
12234            }
12235            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12236            pw.println();
12237            if (dumpAll) {
12238                pw.println("-------------------------------------------------------------------------------");
12239            }
12240            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12241            pw.println();
12242            if (dumpAll) {
12243                pw.println("-------------------------------------------------------------------------------");
12244            }
12245            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12246            pw.println();
12247            if (dumpAll) {
12248                pw.println("-------------------------------------------------------------------------------");
12249            }
12250            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12251            pw.println();
12252            if (dumpAll) {
12253                pw.println("-------------------------------------------------------------------------------");
12254            }
12255            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12256            pw.println();
12257            if (dumpAll) {
12258                pw.println("-------------------------------------------------------------------------------");
12259            }
12260            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12261        }
12262        Binder.restoreCallingIdentity(origId);
12263    }
12264
12265    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12266            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12267        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12268
12269        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12270                dumpPackage);
12271        boolean needSep = printedAnything;
12272
12273        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12274                dumpPackage, needSep, "  mFocusedActivity: ");
12275        if (printed) {
12276            printedAnything = true;
12277            needSep = false;
12278        }
12279
12280        if (dumpPackage == null) {
12281            if (needSep) {
12282                pw.println();
12283            }
12284            needSep = true;
12285            printedAnything = true;
12286            mStackSupervisor.dump(pw, "  ");
12287        }
12288
12289        if (!printedAnything) {
12290            pw.println("  (nothing)");
12291        }
12292    }
12293
12294    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12295            int opti, boolean dumpAll, String dumpPackage) {
12296        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12297
12298        boolean printedAnything = false;
12299
12300        if (mRecentTasks.size() > 0) {
12301            boolean printedHeader = false;
12302
12303            final int N = mRecentTasks.size();
12304            for (int i=0; i<N; i++) {
12305                TaskRecord tr = mRecentTasks.get(i);
12306                if (dumpPackage != null) {
12307                    if (tr.realActivity == null ||
12308                            !dumpPackage.equals(tr.realActivity)) {
12309                        continue;
12310                    }
12311                }
12312                if (!printedHeader) {
12313                    pw.println("  Recent tasks:");
12314                    printedHeader = true;
12315                    printedAnything = true;
12316                }
12317                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12318                        pw.println(tr);
12319                if (dumpAll) {
12320                    mRecentTasks.get(i).dump(pw, "    ");
12321                }
12322            }
12323        }
12324
12325        if (!printedAnything) {
12326            pw.println("  (nothing)");
12327        }
12328    }
12329
12330    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12331            int opti, boolean dumpAll, String dumpPackage) {
12332        boolean needSep = false;
12333        boolean printedAnything = false;
12334        int numPers = 0;
12335
12336        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12337
12338        if (dumpAll) {
12339            final int NP = mProcessNames.getMap().size();
12340            for (int ip=0; ip<NP; ip++) {
12341                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12342                final int NA = procs.size();
12343                for (int ia=0; ia<NA; ia++) {
12344                    ProcessRecord r = procs.valueAt(ia);
12345                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12346                        continue;
12347                    }
12348                    if (!needSep) {
12349                        pw.println("  All known processes:");
12350                        needSep = true;
12351                        printedAnything = true;
12352                    }
12353                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12354                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12355                        pw.print(" "); pw.println(r);
12356                    r.dump(pw, "    ");
12357                    if (r.persistent) {
12358                        numPers++;
12359                    }
12360                }
12361            }
12362        }
12363
12364        if (mIsolatedProcesses.size() > 0) {
12365            boolean printed = false;
12366            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12367                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12368                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12369                    continue;
12370                }
12371                if (!printed) {
12372                    if (needSep) {
12373                        pw.println();
12374                    }
12375                    pw.println("  Isolated process list (sorted by uid):");
12376                    printedAnything = true;
12377                    printed = true;
12378                    needSep = true;
12379                }
12380                pw.println(String.format("%sIsolated #%2d: %s",
12381                        "    ", i, r.toString()));
12382            }
12383        }
12384
12385        if (mLruProcesses.size() > 0) {
12386            if (needSep) {
12387                pw.println();
12388            }
12389            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12390                    pw.print(" total, non-act at ");
12391                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12392                    pw.print(", non-svc at ");
12393                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12394                    pw.println("):");
12395            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12396            needSep = true;
12397            printedAnything = true;
12398        }
12399
12400        if (dumpAll || dumpPackage != null) {
12401            synchronized (mPidsSelfLocked) {
12402                boolean printed = false;
12403                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12404                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12405                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12406                        continue;
12407                    }
12408                    if (!printed) {
12409                        if (needSep) pw.println();
12410                        needSep = true;
12411                        pw.println("  PID mappings:");
12412                        printed = true;
12413                        printedAnything = true;
12414                    }
12415                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12416                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12417                }
12418            }
12419        }
12420
12421        if (mForegroundProcesses.size() > 0) {
12422            synchronized (mPidsSelfLocked) {
12423                boolean printed = false;
12424                for (int i=0; i<mForegroundProcesses.size(); i++) {
12425                    ProcessRecord r = mPidsSelfLocked.get(
12426                            mForegroundProcesses.valueAt(i).pid);
12427                    if (dumpPackage != null && (r == null
12428                            || !r.pkgList.containsKey(dumpPackage))) {
12429                        continue;
12430                    }
12431                    if (!printed) {
12432                        if (needSep) pw.println();
12433                        needSep = true;
12434                        pw.println("  Foreground Processes:");
12435                        printed = true;
12436                        printedAnything = true;
12437                    }
12438                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12439                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12440                }
12441            }
12442        }
12443
12444        if (mPersistentStartingProcesses.size() > 0) {
12445            if (needSep) pw.println();
12446            needSep = true;
12447            printedAnything = true;
12448            pw.println("  Persisent processes that are starting:");
12449            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12450                    "Starting Norm", "Restarting PERS", dumpPackage);
12451        }
12452
12453        if (mRemovedProcesses.size() > 0) {
12454            if (needSep) pw.println();
12455            needSep = true;
12456            printedAnything = true;
12457            pw.println("  Processes that are being removed:");
12458            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12459                    "Removed Norm", "Removed PERS", dumpPackage);
12460        }
12461
12462        if (mProcessesOnHold.size() > 0) {
12463            if (needSep) pw.println();
12464            needSep = true;
12465            printedAnything = true;
12466            pw.println("  Processes that are on old until the system is ready:");
12467            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12468                    "OnHold Norm", "OnHold PERS", dumpPackage);
12469        }
12470
12471        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12472
12473        if (mProcessCrashTimes.getMap().size() > 0) {
12474            boolean printed = false;
12475            long now = SystemClock.uptimeMillis();
12476            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12477            final int NP = pmap.size();
12478            for (int ip=0; ip<NP; ip++) {
12479                String pname = pmap.keyAt(ip);
12480                SparseArray<Long> uids = pmap.valueAt(ip);
12481                final int N = uids.size();
12482                for (int i=0; i<N; i++) {
12483                    int puid = uids.keyAt(i);
12484                    ProcessRecord r = mProcessNames.get(pname, puid);
12485                    if (dumpPackage != null && (r == null
12486                            || !r.pkgList.containsKey(dumpPackage))) {
12487                        continue;
12488                    }
12489                    if (!printed) {
12490                        if (needSep) pw.println();
12491                        needSep = true;
12492                        pw.println("  Time since processes crashed:");
12493                        printed = true;
12494                        printedAnything = true;
12495                    }
12496                    pw.print("    Process "); pw.print(pname);
12497                            pw.print(" uid "); pw.print(puid);
12498                            pw.print(": last crashed ");
12499                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12500                            pw.println(" ago");
12501                }
12502            }
12503        }
12504
12505        if (mBadProcesses.getMap().size() > 0) {
12506            boolean printed = false;
12507            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12508            final int NP = pmap.size();
12509            for (int ip=0; ip<NP; ip++) {
12510                String pname = pmap.keyAt(ip);
12511                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12512                final int N = uids.size();
12513                for (int i=0; i<N; i++) {
12514                    int puid = uids.keyAt(i);
12515                    ProcessRecord r = mProcessNames.get(pname, puid);
12516                    if (dumpPackage != null && (r == null
12517                            || !r.pkgList.containsKey(dumpPackage))) {
12518                        continue;
12519                    }
12520                    if (!printed) {
12521                        if (needSep) pw.println();
12522                        needSep = true;
12523                        pw.println("  Bad processes:");
12524                        printedAnything = true;
12525                    }
12526                    BadProcessInfo info = uids.valueAt(i);
12527                    pw.print("    Bad process "); pw.print(pname);
12528                            pw.print(" uid "); pw.print(puid);
12529                            pw.print(": crashed at time "); pw.println(info.time);
12530                    if (info.shortMsg != null) {
12531                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12532                    }
12533                    if (info.longMsg != null) {
12534                        pw.print("      Long msg: "); pw.println(info.longMsg);
12535                    }
12536                    if (info.stack != null) {
12537                        pw.println("      Stack:");
12538                        int lastPos = 0;
12539                        for (int pos=0; pos<info.stack.length(); pos++) {
12540                            if (info.stack.charAt(pos) == '\n') {
12541                                pw.print("        ");
12542                                pw.write(info.stack, lastPos, pos-lastPos);
12543                                pw.println();
12544                                lastPos = pos+1;
12545                            }
12546                        }
12547                        if (lastPos < info.stack.length()) {
12548                            pw.print("        ");
12549                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12550                            pw.println();
12551                        }
12552                    }
12553                }
12554            }
12555        }
12556
12557        if (dumpPackage == null) {
12558            pw.println();
12559            needSep = false;
12560            pw.println("  mStartedUsers:");
12561            for (int i=0; i<mStartedUsers.size(); i++) {
12562                UserStartedState uss = mStartedUsers.valueAt(i);
12563                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12564                        pw.print(": "); uss.dump("", pw);
12565            }
12566            pw.print("  mStartedUserArray: [");
12567            for (int i=0; i<mStartedUserArray.length; i++) {
12568                if (i > 0) pw.print(", ");
12569                pw.print(mStartedUserArray[i]);
12570            }
12571            pw.println("]");
12572            pw.print("  mUserLru: [");
12573            for (int i=0; i<mUserLru.size(); i++) {
12574                if (i > 0) pw.print(", ");
12575                pw.print(mUserLru.get(i));
12576            }
12577            pw.println("]");
12578            if (dumpAll) {
12579                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12580            }
12581            synchronized (mUserProfileGroupIdsSelfLocked) {
12582                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12583                    pw.println("  mUserProfileGroupIds:");
12584                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12585                        pw.print("    User #");
12586                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12587                        pw.print(" -> profile #");
12588                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12589                    }
12590                }
12591            }
12592        }
12593        if (mHomeProcess != null && (dumpPackage == null
12594                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12595            if (needSep) {
12596                pw.println();
12597                needSep = false;
12598            }
12599            pw.println("  mHomeProcess: " + mHomeProcess);
12600        }
12601        if (mPreviousProcess != null && (dumpPackage == null
12602                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12603            if (needSep) {
12604                pw.println();
12605                needSep = false;
12606            }
12607            pw.println("  mPreviousProcess: " + mPreviousProcess);
12608        }
12609        if (dumpAll) {
12610            StringBuilder sb = new StringBuilder(128);
12611            sb.append("  mPreviousProcessVisibleTime: ");
12612            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12613            pw.println(sb);
12614        }
12615        if (mHeavyWeightProcess != null && (dumpPackage == null
12616                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12617            if (needSep) {
12618                pw.println();
12619                needSep = false;
12620            }
12621            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12622        }
12623        if (dumpPackage == null) {
12624            pw.println("  mConfiguration: " + mConfiguration);
12625        }
12626        if (dumpAll) {
12627            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12628            if (mCompatModePackages.getPackages().size() > 0) {
12629                boolean printed = false;
12630                for (Map.Entry<String, Integer> entry
12631                        : mCompatModePackages.getPackages().entrySet()) {
12632                    String pkg = entry.getKey();
12633                    int mode = entry.getValue();
12634                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12635                        continue;
12636                    }
12637                    if (!printed) {
12638                        pw.println("  mScreenCompatPackages:");
12639                        printed = true;
12640                    }
12641                    pw.print("    "); pw.print(pkg); pw.print(": ");
12642                            pw.print(mode); pw.println();
12643                }
12644            }
12645        }
12646        if (dumpPackage == null) {
12647            if (mSleeping || mWentToSleep || mLockScreenShown) {
12648                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12649                        + " mLockScreenShown " + mLockScreenShown);
12650            }
12651            if (mShuttingDown || mRunningVoice) {
12652                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12653            }
12654        }
12655        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12656                || mOrigWaitForDebugger) {
12657            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12658                    || dumpPackage.equals(mOrigDebugApp)) {
12659                if (needSep) {
12660                    pw.println();
12661                    needSep = false;
12662                }
12663                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12664                        + " mDebugTransient=" + mDebugTransient
12665                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12666            }
12667        }
12668        if (mOpenGlTraceApp != null) {
12669            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12670                if (needSep) {
12671                    pw.println();
12672                    needSep = false;
12673                }
12674                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12675            }
12676        }
12677        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12678                || mProfileFd != null) {
12679            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12680                if (needSep) {
12681                    pw.println();
12682                    needSep = false;
12683                }
12684                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12685                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12686                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12687                        + mAutoStopProfiler);
12688                pw.println("  mProfileType=" + mProfileType);
12689            }
12690        }
12691        if (dumpPackage == null) {
12692            if (mAlwaysFinishActivities || mController != null) {
12693                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12694                        + " mController=" + mController);
12695            }
12696            if (dumpAll) {
12697                pw.println("  Total persistent processes: " + numPers);
12698                pw.println("  mProcessesReady=" + mProcessesReady
12699                        + " mSystemReady=" + mSystemReady);
12700                pw.println("  mBooting=" + mBooting
12701                        + " mBooted=" + mBooted
12702                        + " mFactoryTest=" + mFactoryTest);
12703                pw.print("  mLastPowerCheckRealtime=");
12704                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12705                        pw.println("");
12706                pw.print("  mLastPowerCheckUptime=");
12707                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12708                        pw.println("");
12709                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12710                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12711                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12712                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12713                        + " (" + mLruProcesses.size() + " total)"
12714                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12715                        + " mNumServiceProcs=" + mNumServiceProcs
12716                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12717                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12718                        + " mLastMemoryLevel" + mLastMemoryLevel
12719                        + " mLastNumProcesses" + mLastNumProcesses);
12720                long now = SystemClock.uptimeMillis();
12721                pw.print("  mLastIdleTime=");
12722                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12723                        pw.print(" mLowRamSinceLastIdle=");
12724                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12725                        pw.println();
12726            }
12727        }
12728
12729        if (!printedAnything) {
12730            pw.println("  (nothing)");
12731        }
12732    }
12733
12734    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12735            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12736        if (mProcessesToGc.size() > 0) {
12737            boolean printed = false;
12738            long now = SystemClock.uptimeMillis();
12739            for (int i=0; i<mProcessesToGc.size(); i++) {
12740                ProcessRecord proc = mProcessesToGc.get(i);
12741                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12742                    continue;
12743                }
12744                if (!printed) {
12745                    if (needSep) pw.println();
12746                    needSep = true;
12747                    pw.println("  Processes that are waiting to GC:");
12748                    printed = true;
12749                }
12750                pw.print("    Process "); pw.println(proc);
12751                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12752                        pw.print(", last gced=");
12753                        pw.print(now-proc.lastRequestedGc);
12754                        pw.print(" ms ago, last lowMem=");
12755                        pw.print(now-proc.lastLowMemory);
12756                        pw.println(" ms ago");
12757
12758            }
12759        }
12760        return needSep;
12761    }
12762
12763    void printOomLevel(PrintWriter pw, String name, int adj) {
12764        pw.print("    ");
12765        if (adj >= 0) {
12766            pw.print(' ');
12767            if (adj < 10) pw.print(' ');
12768        } else {
12769            if (adj > -10) pw.print(' ');
12770        }
12771        pw.print(adj);
12772        pw.print(": ");
12773        pw.print(name);
12774        pw.print(" (");
12775        pw.print(mProcessList.getMemLevel(adj)/1024);
12776        pw.println(" kB)");
12777    }
12778
12779    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12780            int opti, boolean dumpAll) {
12781        boolean needSep = false;
12782
12783        if (mLruProcesses.size() > 0) {
12784            if (needSep) pw.println();
12785            needSep = true;
12786            pw.println("  OOM levels:");
12787            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12788            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12789            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12790            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12791            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12792            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12793            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12794            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12795            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12796            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12797            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12798            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12799            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12800
12801            if (needSep) pw.println();
12802            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12803                    pw.print(" total, non-act at ");
12804                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12805                    pw.print(", non-svc at ");
12806                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12807                    pw.println("):");
12808            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12809            needSep = true;
12810        }
12811
12812        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12813
12814        pw.println();
12815        pw.println("  mHomeProcess: " + mHomeProcess);
12816        pw.println("  mPreviousProcess: " + mPreviousProcess);
12817        if (mHeavyWeightProcess != null) {
12818            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12819        }
12820
12821        return true;
12822    }
12823
12824    /**
12825     * There are three ways to call this:
12826     *  - no provider specified: dump all the providers
12827     *  - a flattened component name that matched an existing provider was specified as the
12828     *    first arg: dump that one provider
12829     *  - the first arg isn't the flattened component name of an existing provider:
12830     *    dump all providers whose component contains the first arg as a substring
12831     */
12832    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12833            int opti, boolean dumpAll) {
12834        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12835    }
12836
12837    static class ItemMatcher {
12838        ArrayList<ComponentName> components;
12839        ArrayList<String> strings;
12840        ArrayList<Integer> objects;
12841        boolean all;
12842
12843        ItemMatcher() {
12844            all = true;
12845        }
12846
12847        void build(String name) {
12848            ComponentName componentName = ComponentName.unflattenFromString(name);
12849            if (componentName != null) {
12850                if (components == null) {
12851                    components = new ArrayList<ComponentName>();
12852                }
12853                components.add(componentName);
12854                all = false;
12855            } else {
12856                int objectId = 0;
12857                // Not a '/' separated full component name; maybe an object ID?
12858                try {
12859                    objectId = Integer.parseInt(name, 16);
12860                    if (objects == null) {
12861                        objects = new ArrayList<Integer>();
12862                    }
12863                    objects.add(objectId);
12864                    all = false;
12865                } catch (RuntimeException e) {
12866                    // Not an integer; just do string match.
12867                    if (strings == null) {
12868                        strings = new ArrayList<String>();
12869                    }
12870                    strings.add(name);
12871                    all = false;
12872                }
12873            }
12874        }
12875
12876        int build(String[] args, int opti) {
12877            for (; opti<args.length; opti++) {
12878                String name = args[opti];
12879                if ("--".equals(name)) {
12880                    return opti+1;
12881                }
12882                build(name);
12883            }
12884            return opti;
12885        }
12886
12887        boolean match(Object object, ComponentName comp) {
12888            if (all) {
12889                return true;
12890            }
12891            if (components != null) {
12892                for (int i=0; i<components.size(); i++) {
12893                    if (components.get(i).equals(comp)) {
12894                        return true;
12895                    }
12896                }
12897            }
12898            if (objects != null) {
12899                for (int i=0; i<objects.size(); i++) {
12900                    if (System.identityHashCode(object) == objects.get(i)) {
12901                        return true;
12902                    }
12903                }
12904            }
12905            if (strings != null) {
12906                String flat = comp.flattenToString();
12907                for (int i=0; i<strings.size(); i++) {
12908                    if (flat.contains(strings.get(i))) {
12909                        return true;
12910                    }
12911                }
12912            }
12913            return false;
12914        }
12915    }
12916
12917    /**
12918     * There are three things that cmd can be:
12919     *  - a flattened component name that matches an existing activity
12920     *  - the cmd arg isn't the flattened component name of an existing activity:
12921     *    dump all activity whose component contains the cmd as a substring
12922     *  - A hex number of the ActivityRecord object instance.
12923     */
12924    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12925            int opti, boolean dumpAll) {
12926        ArrayList<ActivityRecord> activities;
12927
12928        synchronized (this) {
12929            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12930        }
12931
12932        if (activities.size() <= 0) {
12933            return false;
12934        }
12935
12936        String[] newArgs = new String[args.length - opti];
12937        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12938
12939        TaskRecord lastTask = null;
12940        boolean needSep = false;
12941        for (int i=activities.size()-1; i>=0; i--) {
12942            ActivityRecord r = activities.get(i);
12943            if (needSep) {
12944                pw.println();
12945            }
12946            needSep = true;
12947            synchronized (this) {
12948                if (lastTask != r.task) {
12949                    lastTask = r.task;
12950                    pw.print("TASK "); pw.print(lastTask.affinity);
12951                            pw.print(" id="); pw.println(lastTask.taskId);
12952                    if (dumpAll) {
12953                        lastTask.dump(pw, "  ");
12954                    }
12955                }
12956            }
12957            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12958        }
12959        return true;
12960    }
12961
12962    /**
12963     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12964     * there is a thread associated with the activity.
12965     */
12966    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12967            final ActivityRecord r, String[] args, boolean dumpAll) {
12968        String innerPrefix = prefix + "  ";
12969        synchronized (this) {
12970            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12971                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12972                    pw.print(" pid=");
12973                    if (r.app != null) pw.println(r.app.pid);
12974                    else pw.println("(not running)");
12975            if (dumpAll) {
12976                r.dump(pw, innerPrefix);
12977            }
12978        }
12979        if (r.app != null && r.app.thread != null) {
12980            // flush anything that is already in the PrintWriter since the thread is going
12981            // to write to the file descriptor directly
12982            pw.flush();
12983            try {
12984                TransferPipe tp = new TransferPipe();
12985                try {
12986                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12987                            r.appToken, innerPrefix, args);
12988                    tp.go(fd);
12989                } finally {
12990                    tp.kill();
12991                }
12992            } catch (IOException e) {
12993                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12994            } catch (RemoteException e) {
12995                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12996            }
12997        }
12998    }
12999
13000    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13001            int opti, boolean dumpAll, String dumpPackage) {
13002        boolean needSep = false;
13003        boolean onlyHistory = false;
13004        boolean printedAnything = false;
13005
13006        if ("history".equals(dumpPackage)) {
13007            if (opti < args.length && "-s".equals(args[opti])) {
13008                dumpAll = false;
13009            }
13010            onlyHistory = true;
13011            dumpPackage = null;
13012        }
13013
13014        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
13015        if (!onlyHistory && dumpAll) {
13016            if (mRegisteredReceivers.size() > 0) {
13017                boolean printed = false;
13018                Iterator it = mRegisteredReceivers.values().iterator();
13019                while (it.hasNext()) {
13020                    ReceiverList r = (ReceiverList)it.next();
13021                    if (dumpPackage != null && (r.app == null ||
13022                            !dumpPackage.equals(r.app.info.packageName))) {
13023                        continue;
13024                    }
13025                    if (!printed) {
13026                        pw.println("  Registered Receivers:");
13027                        needSep = true;
13028                        printed = true;
13029                        printedAnything = true;
13030                    }
13031                    pw.print("  * "); pw.println(r);
13032                    r.dump(pw, "    ");
13033                }
13034            }
13035
13036            if (mReceiverResolver.dump(pw, needSep ?
13037                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13038                    "    ", dumpPackage, false)) {
13039                needSep = true;
13040                printedAnything = true;
13041            }
13042        }
13043
13044        for (BroadcastQueue q : mBroadcastQueues) {
13045            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13046            printedAnything |= needSep;
13047        }
13048
13049        needSep = true;
13050
13051        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13052            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13053                if (needSep) {
13054                    pw.println();
13055                }
13056                needSep = true;
13057                printedAnything = true;
13058                pw.print("  Sticky broadcasts for user ");
13059                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13060                StringBuilder sb = new StringBuilder(128);
13061                for (Map.Entry<String, ArrayList<Intent>> ent
13062                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13063                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13064                    if (dumpAll) {
13065                        pw.println(":");
13066                        ArrayList<Intent> intents = ent.getValue();
13067                        final int N = intents.size();
13068                        for (int i=0; i<N; i++) {
13069                            sb.setLength(0);
13070                            sb.append("    Intent: ");
13071                            intents.get(i).toShortString(sb, false, true, false, false);
13072                            pw.println(sb.toString());
13073                            Bundle bundle = intents.get(i).getExtras();
13074                            if (bundle != null) {
13075                                pw.print("      ");
13076                                pw.println(bundle.toString());
13077                            }
13078                        }
13079                    } else {
13080                        pw.println("");
13081                    }
13082                }
13083            }
13084        }
13085
13086        if (!onlyHistory && dumpAll) {
13087            pw.println();
13088            for (BroadcastQueue queue : mBroadcastQueues) {
13089                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13090                        + queue.mBroadcastsScheduled);
13091            }
13092            pw.println("  mHandler:");
13093            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13094            needSep = true;
13095            printedAnything = true;
13096        }
13097
13098        if (!printedAnything) {
13099            pw.println("  (nothing)");
13100        }
13101    }
13102
13103    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13104            int opti, boolean dumpAll, String dumpPackage) {
13105        boolean needSep;
13106        boolean printedAnything = false;
13107
13108        ItemMatcher matcher = new ItemMatcher();
13109        matcher.build(args, opti);
13110
13111        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13112
13113        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13114        printedAnything |= needSep;
13115
13116        if (mLaunchingProviders.size() > 0) {
13117            boolean printed = false;
13118            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13119                ContentProviderRecord r = mLaunchingProviders.get(i);
13120                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13121                    continue;
13122                }
13123                if (!printed) {
13124                    if (needSep) pw.println();
13125                    needSep = true;
13126                    pw.println("  Launching content providers:");
13127                    printed = true;
13128                    printedAnything = true;
13129                }
13130                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13131                        pw.println(r);
13132            }
13133        }
13134
13135        if (mGrantedUriPermissions.size() > 0) {
13136            boolean printed = false;
13137            int dumpUid = -2;
13138            if (dumpPackage != null) {
13139                try {
13140                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13141                } catch (NameNotFoundException e) {
13142                    dumpUid = -1;
13143                }
13144            }
13145            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13146                int uid = mGrantedUriPermissions.keyAt(i);
13147                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13148                    continue;
13149                }
13150                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13151                if (!printed) {
13152                    if (needSep) pw.println();
13153                    needSep = true;
13154                    pw.println("  Granted Uri Permissions:");
13155                    printed = true;
13156                    printedAnything = true;
13157                }
13158                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13159                for (UriPermission perm : perms.values()) {
13160                    pw.print("    "); pw.println(perm);
13161                    if (dumpAll) {
13162                        perm.dump(pw, "      ");
13163                    }
13164                }
13165            }
13166        }
13167
13168        if (!printedAnything) {
13169            pw.println("  (nothing)");
13170        }
13171    }
13172
13173    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13174            int opti, boolean dumpAll, String dumpPackage) {
13175        boolean printed = false;
13176
13177        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13178
13179        if (mIntentSenderRecords.size() > 0) {
13180            Iterator<WeakReference<PendingIntentRecord>> it
13181                    = mIntentSenderRecords.values().iterator();
13182            while (it.hasNext()) {
13183                WeakReference<PendingIntentRecord> ref = it.next();
13184                PendingIntentRecord rec = ref != null ? ref.get(): null;
13185                if (dumpPackage != null && (rec == null
13186                        || !dumpPackage.equals(rec.key.packageName))) {
13187                    continue;
13188                }
13189                printed = true;
13190                if (rec != null) {
13191                    pw.print("  * "); pw.println(rec);
13192                    if (dumpAll) {
13193                        rec.dump(pw, "    ");
13194                    }
13195                } else {
13196                    pw.print("  * "); pw.println(ref);
13197                }
13198            }
13199        }
13200
13201        if (!printed) {
13202            pw.println("  (nothing)");
13203        }
13204    }
13205
13206    private static final int dumpProcessList(PrintWriter pw,
13207            ActivityManagerService service, List list,
13208            String prefix, String normalLabel, String persistentLabel,
13209            String dumpPackage) {
13210        int numPers = 0;
13211        final int N = list.size()-1;
13212        for (int i=N; i>=0; i--) {
13213            ProcessRecord r = (ProcessRecord)list.get(i);
13214            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13215                continue;
13216            }
13217            pw.println(String.format("%s%s #%2d: %s",
13218                    prefix, (r.persistent ? persistentLabel : normalLabel),
13219                    i, r.toString()));
13220            if (r.persistent) {
13221                numPers++;
13222            }
13223        }
13224        return numPers;
13225    }
13226
13227    private static final boolean dumpProcessOomList(PrintWriter pw,
13228            ActivityManagerService service, List<ProcessRecord> origList,
13229            String prefix, String normalLabel, String persistentLabel,
13230            boolean inclDetails, String dumpPackage) {
13231
13232        ArrayList<Pair<ProcessRecord, Integer>> list
13233                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13234        for (int i=0; i<origList.size(); i++) {
13235            ProcessRecord r = origList.get(i);
13236            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13237                continue;
13238            }
13239            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13240        }
13241
13242        if (list.size() <= 0) {
13243            return false;
13244        }
13245
13246        Comparator<Pair<ProcessRecord, Integer>> comparator
13247                = new Comparator<Pair<ProcessRecord, Integer>>() {
13248            @Override
13249            public int compare(Pair<ProcessRecord, Integer> object1,
13250                    Pair<ProcessRecord, Integer> object2) {
13251                if (object1.first.setAdj != object2.first.setAdj) {
13252                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13253                }
13254                if (object1.second.intValue() != object2.second.intValue()) {
13255                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13256                }
13257                return 0;
13258            }
13259        };
13260
13261        Collections.sort(list, comparator);
13262
13263        final long curRealtime = SystemClock.elapsedRealtime();
13264        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13265        final long curUptime = SystemClock.uptimeMillis();
13266        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13267
13268        for (int i=list.size()-1; i>=0; i--) {
13269            ProcessRecord r = list.get(i).first;
13270            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13271            char schedGroup;
13272            switch (r.setSchedGroup) {
13273                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13274                    schedGroup = 'B';
13275                    break;
13276                case Process.THREAD_GROUP_DEFAULT:
13277                    schedGroup = 'F';
13278                    break;
13279                default:
13280                    schedGroup = '?';
13281                    break;
13282            }
13283            char foreground;
13284            if (r.foregroundActivities) {
13285                foreground = 'A';
13286            } else if (r.foregroundServices) {
13287                foreground = 'S';
13288            } else {
13289                foreground = ' ';
13290            }
13291            String procState = ProcessList.makeProcStateString(r.curProcState);
13292            pw.print(prefix);
13293            pw.print(r.persistent ? persistentLabel : normalLabel);
13294            pw.print(" #");
13295            int num = (origList.size()-1)-list.get(i).second;
13296            if (num < 10) pw.print(' ');
13297            pw.print(num);
13298            pw.print(": ");
13299            pw.print(oomAdj);
13300            pw.print(' ');
13301            pw.print(schedGroup);
13302            pw.print('/');
13303            pw.print(foreground);
13304            pw.print('/');
13305            pw.print(procState);
13306            pw.print(" trm:");
13307            if (r.trimMemoryLevel < 10) pw.print(' ');
13308            pw.print(r.trimMemoryLevel);
13309            pw.print(' ');
13310            pw.print(r.toShortString());
13311            pw.print(" (");
13312            pw.print(r.adjType);
13313            pw.println(')');
13314            if (r.adjSource != null || r.adjTarget != null) {
13315                pw.print(prefix);
13316                pw.print("    ");
13317                if (r.adjTarget instanceof ComponentName) {
13318                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13319                } else if (r.adjTarget != null) {
13320                    pw.print(r.adjTarget.toString());
13321                } else {
13322                    pw.print("{null}");
13323                }
13324                pw.print("<=");
13325                if (r.adjSource instanceof ProcessRecord) {
13326                    pw.print("Proc{");
13327                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13328                    pw.println("}");
13329                } else if (r.adjSource != null) {
13330                    pw.println(r.adjSource.toString());
13331                } else {
13332                    pw.println("{null}");
13333                }
13334            }
13335            if (inclDetails) {
13336                pw.print(prefix);
13337                pw.print("    ");
13338                pw.print("oom: max="); pw.print(r.maxAdj);
13339                pw.print(" curRaw="); pw.print(r.curRawAdj);
13340                pw.print(" setRaw="); pw.print(r.setRawAdj);
13341                pw.print(" cur="); pw.print(r.curAdj);
13342                pw.print(" set="); pw.println(r.setAdj);
13343                pw.print(prefix);
13344                pw.print("    ");
13345                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13346                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13347                pw.print(" lastPss="); pw.print(r.lastPss);
13348                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13349                pw.print(prefix);
13350                pw.print("    ");
13351                pw.print("cached="); pw.print(r.cached);
13352                pw.print(" empty="); pw.print(r.empty);
13353                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13354
13355                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13356                    if (r.lastWakeTime != 0) {
13357                        long wtime;
13358                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13359                        synchronized (stats) {
13360                            wtime = stats.getProcessWakeTime(r.info.uid,
13361                                    r.pid, curRealtime);
13362                        }
13363                        long timeUsed = wtime - r.lastWakeTime;
13364                        pw.print(prefix);
13365                        pw.print("    ");
13366                        pw.print("keep awake over ");
13367                        TimeUtils.formatDuration(realtimeSince, pw);
13368                        pw.print(" used ");
13369                        TimeUtils.formatDuration(timeUsed, pw);
13370                        pw.print(" (");
13371                        pw.print((timeUsed*100)/realtimeSince);
13372                        pw.println("%)");
13373                    }
13374                    if (r.lastCpuTime != 0) {
13375                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13376                        pw.print(prefix);
13377                        pw.print("    ");
13378                        pw.print("run cpu over ");
13379                        TimeUtils.formatDuration(uptimeSince, pw);
13380                        pw.print(" used ");
13381                        TimeUtils.formatDuration(timeUsed, pw);
13382                        pw.print(" (");
13383                        pw.print((timeUsed*100)/uptimeSince);
13384                        pw.println("%)");
13385                    }
13386                }
13387            }
13388        }
13389        return true;
13390    }
13391
13392    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13393        ArrayList<ProcessRecord> procs;
13394        synchronized (this) {
13395            if (args != null && args.length > start
13396                    && args[start].charAt(0) != '-') {
13397                procs = new ArrayList<ProcessRecord>();
13398                int pid = -1;
13399                try {
13400                    pid = Integer.parseInt(args[start]);
13401                } catch (NumberFormatException e) {
13402                }
13403                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13404                    ProcessRecord proc = mLruProcesses.get(i);
13405                    if (proc.pid == pid) {
13406                        procs.add(proc);
13407                    } else if (proc.processName.equals(args[start])) {
13408                        procs.add(proc);
13409                    }
13410                }
13411                if (procs.size() <= 0) {
13412                    return null;
13413                }
13414            } else {
13415                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13416            }
13417        }
13418        return procs;
13419    }
13420
13421    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13422            PrintWriter pw, String[] args) {
13423        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13424        if (procs == null) {
13425            pw.println("No process found for: " + args[0]);
13426            return;
13427        }
13428
13429        long uptime = SystemClock.uptimeMillis();
13430        long realtime = SystemClock.elapsedRealtime();
13431        pw.println("Applications Graphics Acceleration Info:");
13432        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13433
13434        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13435            ProcessRecord r = procs.get(i);
13436            if (r.thread != null) {
13437                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13438                pw.flush();
13439                try {
13440                    TransferPipe tp = new TransferPipe();
13441                    try {
13442                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13443                        tp.go(fd);
13444                    } finally {
13445                        tp.kill();
13446                    }
13447                } catch (IOException e) {
13448                    pw.println("Failure while dumping the app: " + r);
13449                    pw.flush();
13450                } catch (RemoteException e) {
13451                    pw.println("Got a RemoteException while dumping the app " + r);
13452                    pw.flush();
13453                }
13454            }
13455        }
13456    }
13457
13458    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13459        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13460        if (procs == null) {
13461            pw.println("No process found for: " + args[0]);
13462            return;
13463        }
13464
13465        pw.println("Applications Database Info:");
13466
13467        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13468            ProcessRecord r = procs.get(i);
13469            if (r.thread != null) {
13470                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13471                pw.flush();
13472                try {
13473                    TransferPipe tp = new TransferPipe();
13474                    try {
13475                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13476                        tp.go(fd);
13477                    } finally {
13478                        tp.kill();
13479                    }
13480                } catch (IOException e) {
13481                    pw.println("Failure while dumping the app: " + r);
13482                    pw.flush();
13483                } catch (RemoteException e) {
13484                    pw.println("Got a RemoteException while dumping the app " + r);
13485                    pw.flush();
13486                }
13487            }
13488        }
13489    }
13490
13491    final static class MemItem {
13492        final boolean isProc;
13493        final String label;
13494        final String shortLabel;
13495        final long pss;
13496        final int id;
13497        final boolean hasActivities;
13498        ArrayList<MemItem> subitems;
13499
13500        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13501                boolean _hasActivities) {
13502            isProc = true;
13503            label = _label;
13504            shortLabel = _shortLabel;
13505            pss = _pss;
13506            id = _id;
13507            hasActivities = _hasActivities;
13508        }
13509
13510        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13511            isProc = false;
13512            label = _label;
13513            shortLabel = _shortLabel;
13514            pss = _pss;
13515            id = _id;
13516            hasActivities = false;
13517        }
13518    }
13519
13520    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13521            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13522        if (sort && !isCompact) {
13523            Collections.sort(items, new Comparator<MemItem>() {
13524                @Override
13525                public int compare(MemItem lhs, MemItem rhs) {
13526                    if (lhs.pss < rhs.pss) {
13527                        return 1;
13528                    } else if (lhs.pss > rhs.pss) {
13529                        return -1;
13530                    }
13531                    return 0;
13532                }
13533            });
13534        }
13535
13536        for (int i=0; i<items.size(); i++) {
13537            MemItem mi = items.get(i);
13538            if (!isCompact) {
13539                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13540            } else if (mi.isProc) {
13541                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13542                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13543                pw.println(mi.hasActivities ? ",a" : ",e");
13544            } else {
13545                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13546                pw.println(mi.pss);
13547            }
13548            if (mi.subitems != null) {
13549                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13550                        true, isCompact);
13551            }
13552        }
13553    }
13554
13555    // These are in KB.
13556    static final long[] DUMP_MEM_BUCKETS = new long[] {
13557        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13558        120*1024, 160*1024, 200*1024,
13559        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13560        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13561    };
13562
13563    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13564            boolean stackLike) {
13565        int start = label.lastIndexOf('.');
13566        if (start >= 0) start++;
13567        else start = 0;
13568        int end = label.length();
13569        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13570            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13571                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13572                out.append(bucket);
13573                out.append(stackLike ? "MB." : "MB ");
13574                out.append(label, start, end);
13575                return;
13576            }
13577        }
13578        out.append(memKB/1024);
13579        out.append(stackLike ? "MB." : "MB ");
13580        out.append(label, start, end);
13581    }
13582
13583    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13584            ProcessList.NATIVE_ADJ,
13585            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13586            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13587            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13588            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13589            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13590    };
13591    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13592            "Native",
13593            "System", "Persistent", "Foreground",
13594            "Visible", "Perceptible",
13595            "Heavy Weight", "Backup",
13596            "A Services", "Home",
13597            "Previous", "B Services", "Cached"
13598    };
13599    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13600            "native",
13601            "sys", "pers", "fore",
13602            "vis", "percept",
13603            "heavy", "backup",
13604            "servicea", "home",
13605            "prev", "serviceb", "cached"
13606    };
13607
13608    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13609            long realtime, boolean isCheckinRequest, boolean isCompact) {
13610        if (isCheckinRequest || isCompact) {
13611            // short checkin version
13612            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13613        } else {
13614            pw.println("Applications Memory Usage (kB):");
13615            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13616        }
13617    }
13618
13619    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13620            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13621        boolean dumpDetails = false;
13622        boolean dumpFullDetails = false;
13623        boolean dumpDalvik = false;
13624        boolean oomOnly = false;
13625        boolean isCompact = false;
13626        boolean localOnly = false;
13627
13628        int opti = 0;
13629        while (opti < args.length) {
13630            String opt = args[opti];
13631            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13632                break;
13633            }
13634            opti++;
13635            if ("-a".equals(opt)) {
13636                dumpDetails = true;
13637                dumpFullDetails = true;
13638                dumpDalvik = true;
13639            } else if ("-d".equals(opt)) {
13640                dumpDalvik = true;
13641            } else if ("-c".equals(opt)) {
13642                isCompact = true;
13643            } else if ("--oom".equals(opt)) {
13644                oomOnly = true;
13645            } else if ("--local".equals(opt)) {
13646                localOnly = true;
13647            } else if ("-h".equals(opt)) {
13648                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13649                pw.println("  -a: include all available information for each process.");
13650                pw.println("  -d: include dalvik details when dumping process details.");
13651                pw.println("  -c: dump in a compact machine-parseable representation.");
13652                pw.println("  --oom: only show processes organized by oom adj.");
13653                pw.println("  --local: only collect details locally, don't call process.");
13654                pw.println("If [process] is specified it can be the name or ");
13655                pw.println("pid of a specific process to dump.");
13656                return;
13657            } else {
13658                pw.println("Unknown argument: " + opt + "; use -h for help");
13659            }
13660        }
13661
13662        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13663        long uptime = SystemClock.uptimeMillis();
13664        long realtime = SystemClock.elapsedRealtime();
13665        final long[] tmpLong = new long[1];
13666
13667        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13668        if (procs == null) {
13669            // No Java processes.  Maybe they want to print a native process.
13670            if (args != null && args.length > opti
13671                    && args[opti].charAt(0) != '-') {
13672                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13673                        = new ArrayList<ProcessCpuTracker.Stats>();
13674                updateCpuStatsNow();
13675                int findPid = -1;
13676                try {
13677                    findPid = Integer.parseInt(args[opti]);
13678                } catch (NumberFormatException e) {
13679                }
13680                synchronized (mProcessCpuThread) {
13681                    final int N = mProcessCpuTracker.countStats();
13682                    for (int i=0; i<N; i++) {
13683                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13684                        if (st.pid == findPid || (st.baseName != null
13685                                && st.baseName.equals(args[opti]))) {
13686                            nativeProcs.add(st);
13687                        }
13688                    }
13689                }
13690                if (nativeProcs.size() > 0) {
13691                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13692                            isCompact);
13693                    Debug.MemoryInfo mi = null;
13694                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13695                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13696                        final int pid = r.pid;
13697                        if (!isCheckinRequest && dumpDetails) {
13698                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13699                        }
13700                        if (mi == null) {
13701                            mi = new Debug.MemoryInfo();
13702                        }
13703                        if (dumpDetails || (!brief && !oomOnly)) {
13704                            Debug.getMemoryInfo(pid, mi);
13705                        } else {
13706                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13707                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13708                        }
13709                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13710                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13711                        if (isCheckinRequest) {
13712                            pw.println();
13713                        }
13714                    }
13715                    return;
13716                }
13717            }
13718            pw.println("No process found for: " + args[opti]);
13719            return;
13720        }
13721
13722        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13723            dumpDetails = true;
13724        }
13725
13726        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13727
13728        String[] innerArgs = new String[args.length-opti];
13729        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13730
13731        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13732        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13733        long nativePss=0, dalvikPss=0, otherPss=0;
13734        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13735
13736        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13737        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13738                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13739
13740        long totalPss = 0;
13741        long cachedPss = 0;
13742
13743        Debug.MemoryInfo mi = null;
13744        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13745            final ProcessRecord r = procs.get(i);
13746            final IApplicationThread thread;
13747            final int pid;
13748            final int oomAdj;
13749            final boolean hasActivities;
13750            synchronized (this) {
13751                thread = r.thread;
13752                pid = r.pid;
13753                oomAdj = r.getSetAdjWithServices();
13754                hasActivities = r.activities.size() > 0;
13755            }
13756            if (thread != null) {
13757                if (!isCheckinRequest && dumpDetails) {
13758                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13759                }
13760                if (mi == null) {
13761                    mi = new Debug.MemoryInfo();
13762                }
13763                if (dumpDetails || (!brief && !oomOnly)) {
13764                    Debug.getMemoryInfo(pid, mi);
13765                } else {
13766                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13767                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13768                }
13769                if (dumpDetails) {
13770                    if (localOnly) {
13771                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13772                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13773                        if (isCheckinRequest) {
13774                            pw.println();
13775                        }
13776                    } else {
13777                        try {
13778                            pw.flush();
13779                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13780                                    dumpDalvik, innerArgs);
13781                        } catch (RemoteException e) {
13782                            if (!isCheckinRequest) {
13783                                pw.println("Got RemoteException!");
13784                                pw.flush();
13785                            }
13786                        }
13787                    }
13788                }
13789
13790                final long myTotalPss = mi.getTotalPss();
13791                final long myTotalUss = mi.getTotalUss();
13792
13793                synchronized (this) {
13794                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13795                        // Record this for posterity if the process has been stable.
13796                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13797                    }
13798                }
13799
13800                if (!isCheckinRequest && mi != null) {
13801                    totalPss += myTotalPss;
13802                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13803                            (hasActivities ? " / activities)" : ")"),
13804                            r.processName, myTotalPss, pid, hasActivities);
13805                    procMems.add(pssItem);
13806                    procMemsMap.put(pid, pssItem);
13807
13808                    nativePss += mi.nativePss;
13809                    dalvikPss += mi.dalvikPss;
13810                    otherPss += mi.otherPss;
13811                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13812                        long mem = mi.getOtherPss(j);
13813                        miscPss[j] += mem;
13814                        otherPss -= mem;
13815                    }
13816
13817                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13818                        cachedPss += myTotalPss;
13819                    }
13820
13821                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13822                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13823                                || oomIndex == (oomPss.length-1)) {
13824                            oomPss[oomIndex] += myTotalPss;
13825                            if (oomProcs[oomIndex] == null) {
13826                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13827                            }
13828                            oomProcs[oomIndex].add(pssItem);
13829                            break;
13830                        }
13831                    }
13832                }
13833            }
13834        }
13835
13836        long nativeProcTotalPss = 0;
13837
13838        if (!isCheckinRequest && procs.size() > 1) {
13839            // If we are showing aggregations, also look for native processes to
13840            // include so that our aggregations are more accurate.
13841            updateCpuStatsNow();
13842            synchronized (mProcessCpuThread) {
13843                final int N = mProcessCpuTracker.countStats();
13844                for (int i=0; i<N; i++) {
13845                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13846                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13847                        if (mi == null) {
13848                            mi = new Debug.MemoryInfo();
13849                        }
13850                        if (!brief && !oomOnly) {
13851                            Debug.getMemoryInfo(st.pid, mi);
13852                        } else {
13853                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13854                            mi.nativePrivateDirty = (int)tmpLong[0];
13855                        }
13856
13857                        final long myTotalPss = mi.getTotalPss();
13858                        totalPss += myTotalPss;
13859                        nativeProcTotalPss += myTotalPss;
13860
13861                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13862                                st.name, myTotalPss, st.pid, false);
13863                        procMems.add(pssItem);
13864
13865                        nativePss += mi.nativePss;
13866                        dalvikPss += mi.dalvikPss;
13867                        otherPss += mi.otherPss;
13868                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13869                            long mem = mi.getOtherPss(j);
13870                            miscPss[j] += mem;
13871                            otherPss -= mem;
13872                        }
13873                        oomPss[0] += myTotalPss;
13874                        if (oomProcs[0] == null) {
13875                            oomProcs[0] = new ArrayList<MemItem>();
13876                        }
13877                        oomProcs[0].add(pssItem);
13878                    }
13879                }
13880            }
13881
13882            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13883
13884            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13885            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13886            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13887            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13888                String label = Debug.MemoryInfo.getOtherLabel(j);
13889                catMems.add(new MemItem(label, label, miscPss[j], j));
13890            }
13891
13892            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13893            for (int j=0; j<oomPss.length; j++) {
13894                if (oomPss[j] != 0) {
13895                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13896                            : DUMP_MEM_OOM_LABEL[j];
13897                    MemItem item = new MemItem(label, label, oomPss[j],
13898                            DUMP_MEM_OOM_ADJ[j]);
13899                    item.subitems = oomProcs[j];
13900                    oomMems.add(item);
13901                }
13902            }
13903
13904            if (!brief && !oomOnly && !isCompact) {
13905                pw.println();
13906                pw.println("Total PSS by process:");
13907                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13908                pw.println();
13909            }
13910            if (!isCompact) {
13911                pw.println("Total PSS by OOM adjustment:");
13912            }
13913            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13914            if (!brief && !oomOnly) {
13915                PrintWriter out = categoryPw != null ? categoryPw : pw;
13916                if (!isCompact) {
13917                    out.println();
13918                    out.println("Total PSS by category:");
13919                }
13920                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13921            }
13922            if (!isCompact) {
13923                pw.println();
13924            }
13925            MemInfoReader memInfo = new MemInfoReader();
13926            memInfo.readMemInfo();
13927            if (nativeProcTotalPss > 0) {
13928                synchronized (this) {
13929                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13930                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13931                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13932                            nativeProcTotalPss);
13933                }
13934            }
13935            if (!brief) {
13936                if (!isCompact) {
13937                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13938                    pw.print(" kB (status ");
13939                    switch (mLastMemoryLevel) {
13940                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13941                            pw.println("normal)");
13942                            break;
13943                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13944                            pw.println("moderate)");
13945                            break;
13946                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13947                            pw.println("low)");
13948                            break;
13949                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13950                            pw.println("critical)");
13951                            break;
13952                        default:
13953                            pw.print(mLastMemoryLevel);
13954                            pw.println(")");
13955                            break;
13956                    }
13957                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13958                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13959                            pw.print(cachedPss); pw.print(" cached pss + ");
13960                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13961                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13962                } else {
13963                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13964                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13965                            + memInfo.getFreeSizeKb()); pw.print(",");
13966                    pw.println(totalPss - cachedPss);
13967                }
13968            }
13969            if (!isCompact) {
13970                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13971                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13972                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13973                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13974                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13975                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13976                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13977                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13978                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13979                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13980                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13981            }
13982            if (!brief) {
13983                if (memInfo.getZramTotalSizeKb() != 0) {
13984                    if (!isCompact) {
13985                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13986                                pw.print(" kB physical used for ");
13987                                pw.print(memInfo.getSwapTotalSizeKb()
13988                                        - memInfo.getSwapFreeSizeKb());
13989                                pw.print(" kB in swap (");
13990                                pw.print(memInfo.getSwapTotalSizeKb());
13991                                pw.println(" kB total swap)");
13992                    } else {
13993                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13994                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13995                                pw.println(memInfo.getSwapFreeSizeKb());
13996                    }
13997                }
13998                final int[] SINGLE_LONG_FORMAT = new int[] {
13999                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
14000                };
14001                long[] longOut = new long[1];
14002                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
14003                        SINGLE_LONG_FORMAT, null, longOut, null);
14004                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14005                longOut[0] = 0;
14006                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
14007                        SINGLE_LONG_FORMAT, null, longOut, null);
14008                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14009                longOut[0] = 0;
14010                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
14011                        SINGLE_LONG_FORMAT, null, longOut, null);
14012                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14013                longOut[0] = 0;
14014                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
14015                        SINGLE_LONG_FORMAT, null, longOut, null);
14016                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
14017                if (!isCompact) {
14018                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
14019                        pw.print("      KSM: "); pw.print(sharing);
14020                                pw.print(" kB saved from shared ");
14021                                pw.print(shared); pw.println(" kB");
14022                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14023                                pw.print(voltile); pw.println(" kB volatile");
14024                    }
14025                    pw.print("   Tuning: ");
14026                    pw.print(ActivityManager.staticGetMemoryClass());
14027                    pw.print(" (large ");
14028                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14029                    pw.print("), oom ");
14030                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14031                    pw.print(" kB");
14032                    pw.print(", restore limit ");
14033                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14034                    pw.print(" kB");
14035                    if (ActivityManager.isLowRamDeviceStatic()) {
14036                        pw.print(" (low-ram)");
14037                    }
14038                    if (ActivityManager.isHighEndGfx()) {
14039                        pw.print(" (high-end-gfx)");
14040                    }
14041                    pw.println();
14042                } else {
14043                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14044                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14045                    pw.println(voltile);
14046                    pw.print("tuning,");
14047                    pw.print(ActivityManager.staticGetMemoryClass());
14048                    pw.print(',');
14049                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14050                    pw.print(',');
14051                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14052                    if (ActivityManager.isLowRamDeviceStatic()) {
14053                        pw.print(",low-ram");
14054                    }
14055                    if (ActivityManager.isHighEndGfx()) {
14056                        pw.print(",high-end-gfx");
14057                    }
14058                    pw.println();
14059                }
14060            }
14061        }
14062    }
14063
14064    /**
14065     * Searches array of arguments for the specified string
14066     * @param args array of argument strings
14067     * @param value value to search for
14068     * @return true if the value is contained in the array
14069     */
14070    private static boolean scanArgs(String[] args, String value) {
14071        if (args != null) {
14072            for (String arg : args) {
14073                if (value.equals(arg)) {
14074                    return true;
14075                }
14076            }
14077        }
14078        return false;
14079    }
14080
14081    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14082            ContentProviderRecord cpr, boolean always) {
14083        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14084
14085        if (!inLaunching || always) {
14086            synchronized (cpr) {
14087                cpr.launchingApp = null;
14088                cpr.notifyAll();
14089            }
14090            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14091            String names[] = cpr.info.authority.split(";");
14092            for (int j = 0; j < names.length; j++) {
14093                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14094            }
14095        }
14096
14097        for (int i=0; i<cpr.connections.size(); i++) {
14098            ContentProviderConnection conn = cpr.connections.get(i);
14099            if (conn.waiting) {
14100                // If this connection is waiting for the provider, then we don't
14101                // need to mess with its process unless we are always removing
14102                // or for some reason the provider is not currently launching.
14103                if (inLaunching && !always) {
14104                    continue;
14105                }
14106            }
14107            ProcessRecord capp = conn.client;
14108            conn.dead = true;
14109            if (conn.stableCount > 0) {
14110                if (!capp.persistent && capp.thread != null
14111                        && capp.pid != 0
14112                        && capp.pid != MY_PID) {
14113                    capp.kill("depends on provider "
14114                            + cpr.name.flattenToShortString()
14115                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14116                }
14117            } else if (capp.thread != null && conn.provider.provider != null) {
14118                try {
14119                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14120                } catch (RemoteException e) {
14121                }
14122                // In the protocol here, we don't expect the client to correctly
14123                // clean up this connection, we'll just remove it.
14124                cpr.connections.remove(i);
14125                conn.client.conProviders.remove(conn);
14126            }
14127        }
14128
14129        if (inLaunching && always) {
14130            mLaunchingProviders.remove(cpr);
14131        }
14132        return inLaunching;
14133    }
14134
14135    /**
14136     * Main code for cleaning up a process when it has gone away.  This is
14137     * called both as a result of the process dying, or directly when stopping
14138     * a process when running in single process mode.
14139     */
14140    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14141            boolean restarting, boolean allowRestart, int index) {
14142        if (index >= 0) {
14143            removeLruProcessLocked(app);
14144            ProcessList.remove(app.pid);
14145        }
14146
14147        mProcessesToGc.remove(app);
14148        mPendingPssProcesses.remove(app);
14149
14150        // Dismiss any open dialogs.
14151        if (app.crashDialog != null && !app.forceCrashReport) {
14152            app.crashDialog.dismiss();
14153            app.crashDialog = null;
14154        }
14155        if (app.anrDialog != null) {
14156            app.anrDialog.dismiss();
14157            app.anrDialog = null;
14158        }
14159        if (app.waitDialog != null) {
14160            app.waitDialog.dismiss();
14161            app.waitDialog = null;
14162        }
14163
14164        app.crashing = false;
14165        app.notResponding = false;
14166
14167        app.resetPackageList(mProcessStats);
14168        app.unlinkDeathRecipient();
14169        app.makeInactive(mProcessStats);
14170        app.waitingToKill = null;
14171        app.forcingToForeground = null;
14172        updateProcessForegroundLocked(app, false, false);
14173        app.foregroundActivities = false;
14174        app.hasShownUi = false;
14175        app.treatLikeActivity = false;
14176        app.hasAboveClient = false;
14177        app.hasClientActivities = false;
14178
14179        mServices.killServicesLocked(app, allowRestart);
14180
14181        boolean restart = false;
14182
14183        // Remove published content providers.
14184        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14185            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14186            final boolean always = app.bad || !allowRestart;
14187            if (removeDyingProviderLocked(app, cpr, always) || always) {
14188                // We left the provider in the launching list, need to
14189                // restart it.
14190                restart = true;
14191            }
14192
14193            cpr.provider = null;
14194            cpr.proc = null;
14195        }
14196        app.pubProviders.clear();
14197
14198        // Take care of any launching providers waiting for this process.
14199        if (checkAppInLaunchingProvidersLocked(app, false)) {
14200            restart = true;
14201        }
14202
14203        // Unregister from connected content providers.
14204        if (!app.conProviders.isEmpty()) {
14205            for (int i=0; i<app.conProviders.size(); i++) {
14206                ContentProviderConnection conn = app.conProviders.get(i);
14207                conn.provider.connections.remove(conn);
14208            }
14209            app.conProviders.clear();
14210        }
14211
14212        // At this point there may be remaining entries in mLaunchingProviders
14213        // where we were the only one waiting, so they are no longer of use.
14214        // Look for these and clean up if found.
14215        // XXX Commented out for now.  Trying to figure out a way to reproduce
14216        // the actual situation to identify what is actually going on.
14217        if (false) {
14218            for (int i=0; i<mLaunchingProviders.size(); i++) {
14219                ContentProviderRecord cpr = (ContentProviderRecord)
14220                        mLaunchingProviders.get(i);
14221                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14222                    synchronized (cpr) {
14223                        cpr.launchingApp = null;
14224                        cpr.notifyAll();
14225                    }
14226                }
14227            }
14228        }
14229
14230        skipCurrentReceiverLocked(app);
14231
14232        // Unregister any receivers.
14233        for (int i=app.receivers.size()-1; i>=0; i--) {
14234            removeReceiverLocked(app.receivers.valueAt(i));
14235        }
14236        app.receivers.clear();
14237
14238        // If the app is undergoing backup, tell the backup manager about it
14239        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14240            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14241                    + mBackupTarget.appInfo + " died during backup");
14242            try {
14243                IBackupManager bm = IBackupManager.Stub.asInterface(
14244                        ServiceManager.getService(Context.BACKUP_SERVICE));
14245                bm.agentDisconnected(app.info.packageName);
14246            } catch (RemoteException e) {
14247                // can't happen; backup manager is local
14248            }
14249        }
14250
14251        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14252            ProcessChangeItem item = mPendingProcessChanges.get(i);
14253            if (item.pid == app.pid) {
14254                mPendingProcessChanges.remove(i);
14255                mAvailProcessChanges.add(item);
14256            }
14257        }
14258        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14259
14260        // If the caller is restarting this app, then leave it in its
14261        // current lists and let the caller take care of it.
14262        if (restarting) {
14263            return;
14264        }
14265
14266        if (!app.persistent || app.isolated) {
14267            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14268                    "Removing non-persistent process during cleanup: " + app);
14269            mProcessNames.remove(app.processName, app.uid);
14270            mIsolatedProcesses.remove(app.uid);
14271            if (mHeavyWeightProcess == app) {
14272                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14273                        mHeavyWeightProcess.userId, 0));
14274                mHeavyWeightProcess = null;
14275            }
14276        } else if (!app.removed) {
14277            // This app is persistent, so we need to keep its record around.
14278            // If it is not already on the pending app list, add it there
14279            // and start a new process for it.
14280            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14281                mPersistentStartingProcesses.add(app);
14282                restart = true;
14283            }
14284        }
14285        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14286                "Clean-up removing on hold: " + app);
14287        mProcessesOnHold.remove(app);
14288
14289        if (app == mHomeProcess) {
14290            mHomeProcess = null;
14291        }
14292        if (app == mPreviousProcess) {
14293            mPreviousProcess = null;
14294        }
14295
14296        if (restart && !app.isolated) {
14297            // We have components that still need to be running in the
14298            // process, so re-launch it.
14299            mProcessNames.put(app.processName, app.uid, app);
14300            startProcessLocked(app, "restart", app.processName);
14301        } else if (app.pid > 0 && app.pid != MY_PID) {
14302            // Goodbye!
14303            boolean removed;
14304            synchronized (mPidsSelfLocked) {
14305                mPidsSelfLocked.remove(app.pid);
14306                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14307            }
14308            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14309            if (app.isolated) {
14310                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14311            }
14312            app.setPid(0);
14313        }
14314    }
14315
14316    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14317        // Look through the content providers we are waiting to have launched,
14318        // and if any run in this process then either schedule a restart of
14319        // the process or kill the client waiting for it if this process has
14320        // gone bad.
14321        int NL = mLaunchingProviders.size();
14322        boolean restart = false;
14323        for (int i=0; i<NL; i++) {
14324            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14325            if (cpr.launchingApp == app) {
14326                if (!alwaysBad && !app.bad) {
14327                    restart = true;
14328                } else {
14329                    removeDyingProviderLocked(app, cpr, true);
14330                    // cpr should have been removed from mLaunchingProviders
14331                    NL = mLaunchingProviders.size();
14332                    i--;
14333                }
14334            }
14335        }
14336        return restart;
14337    }
14338
14339    // =========================================================
14340    // SERVICES
14341    // =========================================================
14342
14343    @Override
14344    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14345            int flags) {
14346        enforceNotIsolatedCaller("getServices");
14347        synchronized (this) {
14348            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14349        }
14350    }
14351
14352    @Override
14353    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14354        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14355        synchronized (this) {
14356            return mServices.getRunningServiceControlPanelLocked(name);
14357        }
14358    }
14359
14360    @Override
14361    public ComponentName startService(IApplicationThread caller, Intent service,
14362            String resolvedType, int userId) {
14363        enforceNotIsolatedCaller("startService");
14364        // Refuse possible leaked file descriptors
14365        if (service != null && service.hasFileDescriptors() == true) {
14366            throw new IllegalArgumentException("File descriptors passed in Intent");
14367        }
14368
14369        if (DEBUG_SERVICE)
14370            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14371        synchronized(this) {
14372            final int callingPid = Binder.getCallingPid();
14373            final int callingUid = Binder.getCallingUid();
14374            final long origId = Binder.clearCallingIdentity();
14375            ComponentName res = mServices.startServiceLocked(caller, service,
14376                    resolvedType, callingPid, callingUid, userId);
14377            Binder.restoreCallingIdentity(origId);
14378            return res;
14379        }
14380    }
14381
14382    ComponentName startServiceInPackage(int uid,
14383            Intent service, String resolvedType, int userId) {
14384        synchronized(this) {
14385            if (DEBUG_SERVICE)
14386                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14387            final long origId = Binder.clearCallingIdentity();
14388            ComponentName res = mServices.startServiceLocked(null, service,
14389                    resolvedType, -1, uid, userId);
14390            Binder.restoreCallingIdentity(origId);
14391            return res;
14392        }
14393    }
14394
14395    @Override
14396    public int stopService(IApplicationThread caller, Intent service,
14397            String resolvedType, int userId) {
14398        enforceNotIsolatedCaller("stopService");
14399        // Refuse possible leaked file descriptors
14400        if (service != null && service.hasFileDescriptors() == true) {
14401            throw new IllegalArgumentException("File descriptors passed in Intent");
14402        }
14403
14404        synchronized(this) {
14405            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14406        }
14407    }
14408
14409    @Override
14410    public IBinder peekService(Intent service, String resolvedType) {
14411        enforceNotIsolatedCaller("peekService");
14412        // Refuse possible leaked file descriptors
14413        if (service != null && service.hasFileDescriptors() == true) {
14414            throw new IllegalArgumentException("File descriptors passed in Intent");
14415        }
14416        synchronized(this) {
14417            return mServices.peekServiceLocked(service, resolvedType);
14418        }
14419    }
14420
14421    @Override
14422    public boolean stopServiceToken(ComponentName className, IBinder token,
14423            int startId) {
14424        synchronized(this) {
14425            return mServices.stopServiceTokenLocked(className, token, startId);
14426        }
14427    }
14428
14429    @Override
14430    public void setServiceForeground(ComponentName className, IBinder token,
14431            int id, Notification notification, boolean removeNotification) {
14432        synchronized(this) {
14433            mServices.setServiceForegroundLocked(className, token, id, notification,
14434                    removeNotification);
14435        }
14436    }
14437
14438    @Override
14439    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14440            boolean requireFull, String name, String callerPackage) {
14441        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14442                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14443    }
14444
14445    int unsafeConvertIncomingUser(int userId) {
14446        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14447                ? mCurrentUserId : userId;
14448    }
14449
14450    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14451            int allowMode, String name, String callerPackage) {
14452        final int callingUserId = UserHandle.getUserId(callingUid);
14453        if (callingUserId == userId) {
14454            return userId;
14455        }
14456
14457        // Note that we may be accessing mCurrentUserId outside of a lock...
14458        // shouldn't be a big deal, if this is being called outside
14459        // of a locked context there is intrinsically a race with
14460        // the value the caller will receive and someone else changing it.
14461        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14462        // we will switch to the calling user if access to the current user fails.
14463        int targetUserId = unsafeConvertIncomingUser(userId);
14464
14465        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14466            final boolean allow;
14467            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14468                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14469                // If the caller has this permission, they always pass go.  And collect $200.
14470                allow = true;
14471            } else if (allowMode == ALLOW_FULL_ONLY) {
14472                // We require full access, sucks to be you.
14473                allow = false;
14474            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14475                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14476                // If the caller does not have either permission, they are always doomed.
14477                allow = false;
14478            } else if (allowMode == ALLOW_NON_FULL) {
14479                // We are blanket allowing non-full access, you lucky caller!
14480                allow = true;
14481            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14482                // We may or may not allow this depending on whether the two users are
14483                // in the same profile.
14484                synchronized (mUserProfileGroupIdsSelfLocked) {
14485                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14486                            UserInfo.NO_PROFILE_GROUP_ID);
14487                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14488                            UserInfo.NO_PROFILE_GROUP_ID);
14489                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14490                            && callingProfile == targetProfile;
14491                }
14492            } else {
14493                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14494            }
14495            if (!allow) {
14496                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14497                    // In this case, they would like to just execute as their
14498                    // owner user instead of failing.
14499                    targetUserId = callingUserId;
14500                } else {
14501                    StringBuilder builder = new StringBuilder(128);
14502                    builder.append("Permission Denial: ");
14503                    builder.append(name);
14504                    if (callerPackage != null) {
14505                        builder.append(" from ");
14506                        builder.append(callerPackage);
14507                    }
14508                    builder.append(" asks to run as user ");
14509                    builder.append(userId);
14510                    builder.append(" but is calling from user ");
14511                    builder.append(UserHandle.getUserId(callingUid));
14512                    builder.append("; this requires ");
14513                    builder.append(INTERACT_ACROSS_USERS_FULL);
14514                    if (allowMode != ALLOW_FULL_ONLY) {
14515                        builder.append(" or ");
14516                        builder.append(INTERACT_ACROSS_USERS);
14517                    }
14518                    String msg = builder.toString();
14519                    Slog.w(TAG, msg);
14520                    throw new SecurityException(msg);
14521                }
14522            }
14523        }
14524        if (!allowAll && targetUserId < 0) {
14525            throw new IllegalArgumentException(
14526                    "Call does not support special user #" + targetUserId);
14527        }
14528        return targetUserId;
14529    }
14530
14531    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14532            String className, int flags) {
14533        boolean result = false;
14534        // For apps that don't have pre-defined UIDs, check for permission
14535        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14536            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14537                if (ActivityManager.checkUidPermission(
14538                        INTERACT_ACROSS_USERS,
14539                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14540                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14541                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14542                            + " requests FLAG_SINGLE_USER, but app does not hold "
14543                            + INTERACT_ACROSS_USERS;
14544                    Slog.w(TAG, msg);
14545                    throw new SecurityException(msg);
14546                }
14547                // Permission passed
14548                result = true;
14549            }
14550        } else if ("system".equals(componentProcessName)) {
14551            result = true;
14552        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14553                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14554            // Phone app is allowed to export singleuser providers.
14555            result = true;
14556        } else {
14557            // App with pre-defined UID, check if it's a persistent app
14558            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14559        }
14560        if (DEBUG_MU) {
14561            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14562                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14563        }
14564        return result;
14565    }
14566
14567    /**
14568     * Checks to see if the caller is in the same app as the singleton
14569     * component, or the component is in a special app. It allows special apps
14570     * to export singleton components but prevents exporting singleton
14571     * components for regular apps.
14572     */
14573    boolean isValidSingletonCall(int callingUid, int componentUid) {
14574        int componentAppId = UserHandle.getAppId(componentUid);
14575        return UserHandle.isSameApp(callingUid, componentUid)
14576                || componentAppId == Process.SYSTEM_UID
14577                || componentAppId == Process.PHONE_UID
14578                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14579                        == PackageManager.PERMISSION_GRANTED;
14580    }
14581
14582    public int bindService(IApplicationThread caller, IBinder token,
14583            Intent service, String resolvedType,
14584            IServiceConnection connection, int flags, int userId) {
14585        enforceNotIsolatedCaller("bindService");
14586        // Refuse possible leaked file descriptors
14587        if (service != null && service.hasFileDescriptors() == true) {
14588            throw new IllegalArgumentException("File descriptors passed in Intent");
14589        }
14590
14591        synchronized(this) {
14592            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14593                    connection, flags, userId);
14594        }
14595    }
14596
14597    public boolean unbindService(IServiceConnection connection) {
14598        synchronized (this) {
14599            return mServices.unbindServiceLocked(connection);
14600        }
14601    }
14602
14603    public void publishService(IBinder token, Intent intent, IBinder service) {
14604        // Refuse possible leaked file descriptors
14605        if (intent != null && intent.hasFileDescriptors() == true) {
14606            throw new IllegalArgumentException("File descriptors passed in Intent");
14607        }
14608
14609        synchronized(this) {
14610            if (!(token instanceof ServiceRecord)) {
14611                throw new IllegalArgumentException("Invalid service token");
14612            }
14613            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14614        }
14615    }
14616
14617    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14618        // Refuse possible leaked file descriptors
14619        if (intent != null && intent.hasFileDescriptors() == true) {
14620            throw new IllegalArgumentException("File descriptors passed in Intent");
14621        }
14622
14623        synchronized(this) {
14624            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14625        }
14626    }
14627
14628    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14629        synchronized(this) {
14630            if (!(token instanceof ServiceRecord)) {
14631                throw new IllegalArgumentException("Invalid service token");
14632            }
14633            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14634        }
14635    }
14636
14637    // =========================================================
14638    // BACKUP AND RESTORE
14639    // =========================================================
14640
14641    // Cause the target app to be launched if necessary and its backup agent
14642    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14643    // activity manager to announce its creation.
14644    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14645        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14646        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14647
14648        synchronized(this) {
14649            // !!! TODO: currently no check here that we're already bound
14650            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14651            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14652            synchronized (stats) {
14653                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14654            }
14655
14656            // Backup agent is now in use, its package can't be stopped.
14657            try {
14658                AppGlobals.getPackageManager().setPackageStoppedState(
14659                        app.packageName, false, UserHandle.getUserId(app.uid));
14660            } catch (RemoteException e) {
14661            } catch (IllegalArgumentException e) {
14662                Slog.w(TAG, "Failed trying to unstop package "
14663                        + app.packageName + ": " + e);
14664            }
14665
14666            BackupRecord r = new BackupRecord(ss, app, backupMode);
14667            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14668                    ? new ComponentName(app.packageName, app.backupAgentName)
14669                    : new ComponentName("android", "FullBackupAgent");
14670            // startProcessLocked() returns existing proc's record if it's already running
14671            ProcessRecord proc = startProcessLocked(app.processName, app,
14672                    false, 0, "backup", hostingName, false, false, false);
14673            if (proc == null) {
14674                Slog.e(TAG, "Unable to start backup agent process " + r);
14675                return false;
14676            }
14677
14678            r.app = proc;
14679            mBackupTarget = r;
14680            mBackupAppName = app.packageName;
14681
14682            // Try not to kill the process during backup
14683            updateOomAdjLocked(proc);
14684
14685            // If the process is already attached, schedule the creation of the backup agent now.
14686            // If it is not yet live, this will be done when it attaches to the framework.
14687            if (proc.thread != null) {
14688                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14689                try {
14690                    proc.thread.scheduleCreateBackupAgent(app,
14691                            compatibilityInfoForPackageLocked(app), backupMode);
14692                } catch (RemoteException e) {
14693                    // Will time out on the backup manager side
14694                }
14695            } else {
14696                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14697            }
14698            // Invariants: at this point, the target app process exists and the application
14699            // is either already running or in the process of coming up.  mBackupTarget and
14700            // mBackupAppName describe the app, so that when it binds back to the AM we
14701            // know that it's scheduled for a backup-agent operation.
14702        }
14703
14704        return true;
14705    }
14706
14707    @Override
14708    public void clearPendingBackup() {
14709        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14710        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14711
14712        synchronized (this) {
14713            mBackupTarget = null;
14714            mBackupAppName = null;
14715        }
14716    }
14717
14718    // A backup agent has just come up
14719    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14720        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14721                + " = " + agent);
14722
14723        synchronized(this) {
14724            if (!agentPackageName.equals(mBackupAppName)) {
14725                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14726                return;
14727            }
14728        }
14729
14730        long oldIdent = Binder.clearCallingIdentity();
14731        try {
14732            IBackupManager bm = IBackupManager.Stub.asInterface(
14733                    ServiceManager.getService(Context.BACKUP_SERVICE));
14734            bm.agentConnected(agentPackageName, agent);
14735        } catch (RemoteException e) {
14736            // can't happen; the backup manager service is local
14737        } catch (Exception e) {
14738            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14739            e.printStackTrace();
14740        } finally {
14741            Binder.restoreCallingIdentity(oldIdent);
14742        }
14743    }
14744
14745    // done with this agent
14746    public void unbindBackupAgent(ApplicationInfo appInfo) {
14747        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14748        if (appInfo == null) {
14749            Slog.w(TAG, "unbind backup agent for null app");
14750            return;
14751        }
14752
14753        synchronized(this) {
14754            try {
14755                if (mBackupAppName == null) {
14756                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14757                    return;
14758                }
14759
14760                if (!mBackupAppName.equals(appInfo.packageName)) {
14761                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14762                    return;
14763                }
14764
14765                // Not backing this app up any more; reset its OOM adjustment
14766                final ProcessRecord proc = mBackupTarget.app;
14767                updateOomAdjLocked(proc);
14768
14769                // If the app crashed during backup, 'thread' will be null here
14770                if (proc.thread != null) {
14771                    try {
14772                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14773                                compatibilityInfoForPackageLocked(appInfo));
14774                    } catch (Exception e) {
14775                        Slog.e(TAG, "Exception when unbinding backup agent:");
14776                        e.printStackTrace();
14777                    }
14778                }
14779            } finally {
14780                mBackupTarget = null;
14781                mBackupAppName = null;
14782            }
14783        }
14784    }
14785    // =========================================================
14786    // BROADCASTS
14787    // =========================================================
14788
14789    private final List getStickiesLocked(String action, IntentFilter filter,
14790            List cur, int userId) {
14791        final ContentResolver resolver = mContext.getContentResolver();
14792        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14793        if (stickies == null) {
14794            return cur;
14795        }
14796        final ArrayList<Intent> list = stickies.get(action);
14797        if (list == null) {
14798            return cur;
14799        }
14800        int N = list.size();
14801        for (int i=0; i<N; i++) {
14802            Intent intent = list.get(i);
14803            if (filter.match(resolver, intent, true, TAG) >= 0) {
14804                if (cur == null) {
14805                    cur = new ArrayList<Intent>();
14806                }
14807                cur.add(intent);
14808            }
14809        }
14810        return cur;
14811    }
14812
14813    boolean isPendingBroadcastProcessLocked(int pid) {
14814        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14815                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14816    }
14817
14818    void skipPendingBroadcastLocked(int pid) {
14819            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14820            for (BroadcastQueue queue : mBroadcastQueues) {
14821                queue.skipPendingBroadcastLocked(pid);
14822            }
14823    }
14824
14825    // The app just attached; send any pending broadcasts that it should receive
14826    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14827        boolean didSomething = false;
14828        for (BroadcastQueue queue : mBroadcastQueues) {
14829            didSomething |= queue.sendPendingBroadcastsLocked(app);
14830        }
14831        return didSomething;
14832    }
14833
14834    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14835            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14836        enforceNotIsolatedCaller("registerReceiver");
14837        int callingUid;
14838        int callingPid;
14839        synchronized(this) {
14840            ProcessRecord callerApp = null;
14841            if (caller != null) {
14842                callerApp = getRecordForAppLocked(caller);
14843                if (callerApp == null) {
14844                    throw new SecurityException(
14845                            "Unable to find app for caller " + caller
14846                            + " (pid=" + Binder.getCallingPid()
14847                            + ") when registering receiver " + receiver);
14848                }
14849                if (callerApp.info.uid != Process.SYSTEM_UID &&
14850                        !callerApp.pkgList.containsKey(callerPackage) &&
14851                        !"android".equals(callerPackage)) {
14852                    throw new SecurityException("Given caller package " + callerPackage
14853                            + " is not running in process " + callerApp);
14854                }
14855                callingUid = callerApp.info.uid;
14856                callingPid = callerApp.pid;
14857            } else {
14858                callerPackage = null;
14859                callingUid = Binder.getCallingUid();
14860                callingPid = Binder.getCallingPid();
14861            }
14862
14863            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14864                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14865
14866            List allSticky = null;
14867
14868            // Look for any matching sticky broadcasts...
14869            Iterator actions = filter.actionsIterator();
14870            if (actions != null) {
14871                while (actions.hasNext()) {
14872                    String action = (String)actions.next();
14873                    allSticky = getStickiesLocked(action, filter, allSticky,
14874                            UserHandle.USER_ALL);
14875                    allSticky = getStickiesLocked(action, filter, allSticky,
14876                            UserHandle.getUserId(callingUid));
14877                }
14878            } else {
14879                allSticky = getStickiesLocked(null, filter, allSticky,
14880                        UserHandle.USER_ALL);
14881                allSticky = getStickiesLocked(null, filter, allSticky,
14882                        UserHandle.getUserId(callingUid));
14883            }
14884
14885            // The first sticky in the list is returned directly back to
14886            // the client.
14887            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14888
14889            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14890                    + ": " + sticky);
14891
14892            if (receiver == null) {
14893                return sticky;
14894            }
14895
14896            ReceiverList rl
14897                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14898            if (rl == null) {
14899                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14900                        userId, receiver);
14901                if (rl.app != null) {
14902                    rl.app.receivers.add(rl);
14903                } else {
14904                    try {
14905                        receiver.asBinder().linkToDeath(rl, 0);
14906                    } catch (RemoteException e) {
14907                        return sticky;
14908                    }
14909                    rl.linkedToDeath = true;
14910                }
14911                mRegisteredReceivers.put(receiver.asBinder(), rl);
14912            } else if (rl.uid != callingUid) {
14913                throw new IllegalArgumentException(
14914                        "Receiver requested to register for uid " + callingUid
14915                        + " was previously registered for uid " + rl.uid);
14916            } else if (rl.pid != callingPid) {
14917                throw new IllegalArgumentException(
14918                        "Receiver requested to register for pid " + callingPid
14919                        + " was previously registered for pid " + rl.pid);
14920            } else if (rl.userId != userId) {
14921                throw new IllegalArgumentException(
14922                        "Receiver requested to register for user " + userId
14923                        + " was previously registered for user " + rl.userId);
14924            }
14925            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14926                    permission, callingUid, userId);
14927            rl.add(bf);
14928            if (!bf.debugCheck()) {
14929                Slog.w(TAG, "==> For Dynamic broadast");
14930            }
14931            mReceiverResolver.addFilter(bf);
14932
14933            // Enqueue broadcasts for all existing stickies that match
14934            // this filter.
14935            if (allSticky != null) {
14936                ArrayList receivers = new ArrayList();
14937                receivers.add(bf);
14938
14939                int N = allSticky.size();
14940                for (int i=0; i<N; i++) {
14941                    Intent intent = (Intent)allSticky.get(i);
14942                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14943                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14944                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14945                            null, null, false, true, true, -1);
14946                    queue.enqueueParallelBroadcastLocked(r);
14947                    queue.scheduleBroadcastsLocked();
14948                }
14949            }
14950
14951            return sticky;
14952        }
14953    }
14954
14955    public void unregisterReceiver(IIntentReceiver receiver) {
14956        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14957
14958        final long origId = Binder.clearCallingIdentity();
14959        try {
14960            boolean doTrim = false;
14961
14962            synchronized(this) {
14963                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14964                if (rl != null) {
14965                    if (rl.curBroadcast != null) {
14966                        BroadcastRecord r = rl.curBroadcast;
14967                        final boolean doNext = finishReceiverLocked(
14968                                receiver.asBinder(), r.resultCode, r.resultData,
14969                                r.resultExtras, r.resultAbort);
14970                        if (doNext) {
14971                            doTrim = true;
14972                            r.queue.processNextBroadcast(false);
14973                        }
14974                    }
14975
14976                    if (rl.app != null) {
14977                        rl.app.receivers.remove(rl);
14978                    }
14979                    removeReceiverLocked(rl);
14980                    if (rl.linkedToDeath) {
14981                        rl.linkedToDeath = false;
14982                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14983                    }
14984                }
14985            }
14986
14987            // If we actually concluded any broadcasts, we might now be able
14988            // to trim the recipients' apps from our working set
14989            if (doTrim) {
14990                trimApplications();
14991                return;
14992            }
14993
14994        } finally {
14995            Binder.restoreCallingIdentity(origId);
14996        }
14997    }
14998
14999    void removeReceiverLocked(ReceiverList rl) {
15000        mRegisteredReceivers.remove(rl.receiver.asBinder());
15001        int N = rl.size();
15002        for (int i=0; i<N; i++) {
15003            mReceiverResolver.removeFilter(rl.get(i));
15004        }
15005    }
15006
15007    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
15008        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
15009            ProcessRecord r = mLruProcesses.get(i);
15010            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
15011                try {
15012                    r.thread.dispatchPackageBroadcast(cmd, packages);
15013                } catch (RemoteException ex) {
15014                }
15015            }
15016        }
15017    }
15018
15019    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
15020            int[] users) {
15021        List<ResolveInfo> receivers = null;
15022        try {
15023            HashSet<ComponentName> singleUserReceivers = null;
15024            boolean scannedFirstReceivers = false;
15025            for (int user : users) {
15026                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15027                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15028                if (user != 0 && newReceivers != null) {
15029                    // If this is not the primary user, we need to check for
15030                    // any receivers that should be filtered out.
15031                    for (int i=0; i<newReceivers.size(); i++) {
15032                        ResolveInfo ri = newReceivers.get(i);
15033                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15034                            newReceivers.remove(i);
15035                            i--;
15036                        }
15037                    }
15038                }
15039                if (newReceivers != null && newReceivers.size() == 0) {
15040                    newReceivers = null;
15041                }
15042                if (receivers == null) {
15043                    receivers = newReceivers;
15044                } else if (newReceivers != null) {
15045                    // We need to concatenate the additional receivers
15046                    // found with what we have do far.  This would be easy,
15047                    // but we also need to de-dup any receivers that are
15048                    // singleUser.
15049                    if (!scannedFirstReceivers) {
15050                        // Collect any single user receivers we had already retrieved.
15051                        scannedFirstReceivers = true;
15052                        for (int i=0; i<receivers.size(); i++) {
15053                            ResolveInfo ri = receivers.get(i);
15054                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15055                                ComponentName cn = new ComponentName(
15056                                        ri.activityInfo.packageName, ri.activityInfo.name);
15057                                if (singleUserReceivers == null) {
15058                                    singleUserReceivers = new HashSet<ComponentName>();
15059                                }
15060                                singleUserReceivers.add(cn);
15061                            }
15062                        }
15063                    }
15064                    // Add the new results to the existing results, tracking
15065                    // and de-dupping single user receivers.
15066                    for (int i=0; i<newReceivers.size(); i++) {
15067                        ResolveInfo ri = newReceivers.get(i);
15068                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15069                            ComponentName cn = new ComponentName(
15070                                    ri.activityInfo.packageName, ri.activityInfo.name);
15071                            if (singleUserReceivers == null) {
15072                                singleUserReceivers = new HashSet<ComponentName>();
15073                            }
15074                            if (!singleUserReceivers.contains(cn)) {
15075                                singleUserReceivers.add(cn);
15076                                receivers.add(ri);
15077                            }
15078                        } else {
15079                            receivers.add(ri);
15080                        }
15081                    }
15082                }
15083            }
15084        } catch (RemoteException ex) {
15085            // pm is in same process, this will never happen.
15086        }
15087        return receivers;
15088    }
15089
15090    private final int broadcastIntentLocked(ProcessRecord callerApp,
15091            String callerPackage, Intent intent, String resolvedType,
15092            IIntentReceiver resultTo, int resultCode, String resultData,
15093            Bundle map, String requiredPermission, int appOp,
15094            boolean ordered, boolean sticky, int callingPid, int callingUid,
15095            int userId) {
15096        intent = new Intent(intent);
15097
15098        // By default broadcasts do not go to stopped apps.
15099        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15100
15101        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15102            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15103            + " ordered=" + ordered + " userid=" + userId);
15104        if ((resultTo != null) && !ordered) {
15105            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15106        }
15107
15108        userId = handleIncomingUser(callingPid, callingUid, userId,
15109                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15110
15111        // Make sure that the user who is receiving this broadcast is started.
15112        // If not, we will just skip it.
15113
15114
15115        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15116            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15117                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15118                Slog.w(TAG, "Skipping broadcast of " + intent
15119                        + ": user " + userId + " is stopped");
15120                return ActivityManager.BROADCAST_SUCCESS;
15121            }
15122        }
15123
15124        /*
15125         * Prevent non-system code (defined here to be non-persistent
15126         * processes) from sending protected broadcasts.
15127         */
15128        int callingAppId = UserHandle.getAppId(callingUid);
15129        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15130            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15131            || callingAppId == Process.NFC_UID || callingUid == 0) {
15132            // Always okay.
15133        } else if (callerApp == null || !callerApp.persistent) {
15134            try {
15135                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15136                        intent.getAction())) {
15137                    String msg = "Permission Denial: not allowed to send broadcast "
15138                            + intent.getAction() + " from pid="
15139                            + callingPid + ", uid=" + callingUid;
15140                    Slog.w(TAG, msg);
15141                    throw new SecurityException(msg);
15142                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15143                    // Special case for compatibility: we don't want apps to send this,
15144                    // but historically it has not been protected and apps may be using it
15145                    // to poke their own app widget.  So, instead of making it protected,
15146                    // just limit it to the caller.
15147                    if (callerApp == null) {
15148                        String msg = "Permission Denial: not allowed to send broadcast "
15149                                + intent.getAction() + " from unknown caller.";
15150                        Slog.w(TAG, msg);
15151                        throw new SecurityException(msg);
15152                    } else if (intent.getComponent() != null) {
15153                        // They are good enough to send to an explicit component...  verify
15154                        // it is being sent to the calling app.
15155                        if (!intent.getComponent().getPackageName().equals(
15156                                callerApp.info.packageName)) {
15157                            String msg = "Permission Denial: not allowed to send broadcast "
15158                                    + intent.getAction() + " to "
15159                                    + intent.getComponent().getPackageName() + " from "
15160                                    + callerApp.info.packageName;
15161                            Slog.w(TAG, msg);
15162                            throw new SecurityException(msg);
15163                        }
15164                    } else {
15165                        // Limit broadcast to their own package.
15166                        intent.setPackage(callerApp.info.packageName);
15167                    }
15168                }
15169            } catch (RemoteException e) {
15170                Slog.w(TAG, "Remote exception", e);
15171                return ActivityManager.BROADCAST_SUCCESS;
15172            }
15173        }
15174
15175        // Handle special intents: if this broadcast is from the package
15176        // manager about a package being removed, we need to remove all of
15177        // its activities from the history stack.
15178        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15179                intent.getAction());
15180        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15181                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15182                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15183                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15184                || uidRemoved) {
15185            if (checkComponentPermission(
15186                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15187                    callingPid, callingUid, -1, true)
15188                    == PackageManager.PERMISSION_GRANTED) {
15189                if (uidRemoved) {
15190                    final Bundle intentExtras = intent.getExtras();
15191                    final int uid = intentExtras != null
15192                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15193                    if (uid >= 0) {
15194                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15195                        synchronized (bs) {
15196                            bs.removeUidStatsLocked(uid);
15197                        }
15198                        mAppOpsService.uidRemoved(uid);
15199                    }
15200                } else {
15201                    // If resources are unavailable just force stop all
15202                    // those packages and flush the attribute cache as well.
15203                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15204                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15205                        if (list != null && (list.length > 0)) {
15206                            for (String pkg : list) {
15207                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15208                                        "storage unmount");
15209                            }
15210                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15211                            sendPackageBroadcastLocked(
15212                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15213                        }
15214                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15215                            intent.getAction())) {
15216                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15217                    } else {
15218                        Uri data = intent.getData();
15219                        String ssp;
15220                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15221                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15222                                    intent.getAction());
15223                            boolean fullUninstall = removed &&
15224                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15225                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15226                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15227                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15228                                        false, fullUninstall, userId,
15229                                        removed ? "pkg removed" : "pkg changed");
15230                            }
15231                            if (removed) {
15232                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15233                                        new String[] {ssp}, userId);
15234                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15235                                    mAppOpsService.packageRemoved(
15236                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15237
15238                                    // Remove all permissions granted from/to this package
15239                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15240                                }
15241                            }
15242                        }
15243                    }
15244                }
15245            } else {
15246                String msg = "Permission Denial: " + intent.getAction()
15247                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15248                        + ", uid=" + callingUid + ")"
15249                        + " requires "
15250                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15251                Slog.w(TAG, msg);
15252                throw new SecurityException(msg);
15253            }
15254
15255        // Special case for adding a package: by default turn on compatibility
15256        // mode.
15257        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15258            Uri data = intent.getData();
15259            String ssp;
15260            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15261                mCompatModePackages.handlePackageAddedLocked(ssp,
15262                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15263            }
15264        }
15265
15266        /*
15267         * If this is the time zone changed action, queue up a message that will reset the timezone
15268         * of all currently running processes. This message will get queued up before the broadcast
15269         * happens.
15270         */
15271        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15272            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15273        }
15274
15275        /*
15276         * If the user set the time, let all running processes know.
15277         */
15278        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15279            final int is24Hour = intent.getBooleanExtra(
15280                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15281            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15282            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15283            synchronized (stats) {
15284                stats.noteCurrentTimeChangedLocked();
15285            }
15286        }
15287
15288        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15289            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15290        }
15291
15292        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15293            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15294            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15295        }
15296
15297        // Add to the sticky list if requested.
15298        if (sticky) {
15299            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15300                    callingPid, callingUid)
15301                    != PackageManager.PERMISSION_GRANTED) {
15302                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15303                        + callingPid + ", uid=" + callingUid
15304                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15305                Slog.w(TAG, msg);
15306                throw new SecurityException(msg);
15307            }
15308            if (requiredPermission != null) {
15309                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15310                        + " and enforce permission " + requiredPermission);
15311                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15312            }
15313            if (intent.getComponent() != null) {
15314                throw new SecurityException(
15315                        "Sticky broadcasts can't target a specific component");
15316            }
15317            // We use userId directly here, since the "all" target is maintained
15318            // as a separate set of sticky broadcasts.
15319            if (userId != UserHandle.USER_ALL) {
15320                // But first, if this is not a broadcast to all users, then
15321                // make sure it doesn't conflict with an existing broadcast to
15322                // all users.
15323                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15324                        UserHandle.USER_ALL);
15325                if (stickies != null) {
15326                    ArrayList<Intent> list = stickies.get(intent.getAction());
15327                    if (list != null) {
15328                        int N = list.size();
15329                        int i;
15330                        for (i=0; i<N; i++) {
15331                            if (intent.filterEquals(list.get(i))) {
15332                                throw new IllegalArgumentException(
15333                                        "Sticky broadcast " + intent + " for user "
15334                                        + userId + " conflicts with existing global broadcast");
15335                            }
15336                        }
15337                    }
15338                }
15339            }
15340            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15341            if (stickies == null) {
15342                stickies = new ArrayMap<String, ArrayList<Intent>>();
15343                mStickyBroadcasts.put(userId, stickies);
15344            }
15345            ArrayList<Intent> list = stickies.get(intent.getAction());
15346            if (list == null) {
15347                list = new ArrayList<Intent>();
15348                stickies.put(intent.getAction(), list);
15349            }
15350            int N = list.size();
15351            int i;
15352            for (i=0; i<N; i++) {
15353                if (intent.filterEquals(list.get(i))) {
15354                    // This sticky already exists, replace it.
15355                    list.set(i, new Intent(intent));
15356                    break;
15357                }
15358            }
15359            if (i >= N) {
15360                list.add(new Intent(intent));
15361            }
15362        }
15363
15364        int[] users;
15365        if (userId == UserHandle.USER_ALL) {
15366            // Caller wants broadcast to go to all started users.
15367            users = mStartedUserArray;
15368        } else {
15369            // Caller wants broadcast to go to one specific user.
15370            users = new int[] {userId};
15371        }
15372
15373        // Figure out who all will receive this broadcast.
15374        List receivers = null;
15375        List<BroadcastFilter> registeredReceivers = null;
15376        // Need to resolve the intent to interested receivers...
15377        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15378                 == 0) {
15379            receivers = collectReceiverComponents(intent, resolvedType, users);
15380        }
15381        if (intent.getComponent() == null) {
15382            registeredReceivers = mReceiverResolver.queryIntent(intent,
15383                    resolvedType, false, userId);
15384        }
15385
15386        final boolean replacePending =
15387                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15388
15389        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15390                + " replacePending=" + replacePending);
15391
15392        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15393        if (!ordered && NR > 0) {
15394            // If we are not serializing this broadcast, then send the
15395            // registered receivers separately so they don't wait for the
15396            // components to be launched.
15397            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15398            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15399                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15400                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15401                    ordered, sticky, false, userId);
15402            if (DEBUG_BROADCAST) Slog.v(
15403                    TAG, "Enqueueing parallel broadcast " + r);
15404            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15405            if (!replaced) {
15406                queue.enqueueParallelBroadcastLocked(r);
15407                queue.scheduleBroadcastsLocked();
15408            }
15409            registeredReceivers = null;
15410            NR = 0;
15411        }
15412
15413        // Merge into one list.
15414        int ir = 0;
15415        if (receivers != null) {
15416            // A special case for PACKAGE_ADDED: do not allow the package
15417            // being added to see this broadcast.  This prevents them from
15418            // using this as a back door to get run as soon as they are
15419            // installed.  Maybe in the future we want to have a special install
15420            // broadcast or such for apps, but we'd like to deliberately make
15421            // this decision.
15422            String skipPackages[] = null;
15423            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15424                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15425                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15426                Uri data = intent.getData();
15427                if (data != null) {
15428                    String pkgName = data.getSchemeSpecificPart();
15429                    if (pkgName != null) {
15430                        skipPackages = new String[] { pkgName };
15431                    }
15432                }
15433            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15434                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15435            }
15436            if (skipPackages != null && (skipPackages.length > 0)) {
15437                for (String skipPackage : skipPackages) {
15438                    if (skipPackage != null) {
15439                        int NT = receivers.size();
15440                        for (int it=0; it<NT; it++) {
15441                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15442                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15443                                receivers.remove(it);
15444                                it--;
15445                                NT--;
15446                            }
15447                        }
15448                    }
15449                }
15450            }
15451
15452            int NT = receivers != null ? receivers.size() : 0;
15453            int it = 0;
15454            ResolveInfo curt = null;
15455            BroadcastFilter curr = null;
15456            while (it < NT && ir < NR) {
15457                if (curt == null) {
15458                    curt = (ResolveInfo)receivers.get(it);
15459                }
15460                if (curr == null) {
15461                    curr = registeredReceivers.get(ir);
15462                }
15463                if (curr.getPriority() >= curt.priority) {
15464                    // Insert this broadcast record into the final list.
15465                    receivers.add(it, curr);
15466                    ir++;
15467                    curr = null;
15468                    it++;
15469                    NT++;
15470                } else {
15471                    // Skip to the next ResolveInfo in the final list.
15472                    it++;
15473                    curt = null;
15474                }
15475            }
15476        }
15477        while (ir < NR) {
15478            if (receivers == null) {
15479                receivers = new ArrayList();
15480            }
15481            receivers.add(registeredReceivers.get(ir));
15482            ir++;
15483        }
15484
15485        if ((receivers != null && receivers.size() > 0)
15486                || resultTo != null) {
15487            BroadcastQueue queue = broadcastQueueForIntent(intent);
15488            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15489                    callerPackage, callingPid, callingUid, resolvedType,
15490                    requiredPermission, appOp, receivers, resultTo, resultCode,
15491                    resultData, map, ordered, sticky, false, userId);
15492            if (DEBUG_BROADCAST) Slog.v(
15493                    TAG, "Enqueueing ordered broadcast " + r
15494                    + ": prev had " + queue.mOrderedBroadcasts.size());
15495            if (DEBUG_BROADCAST) {
15496                int seq = r.intent.getIntExtra("seq", -1);
15497                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15498            }
15499            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15500            if (!replaced) {
15501                queue.enqueueOrderedBroadcastLocked(r);
15502                queue.scheduleBroadcastsLocked();
15503            }
15504        }
15505
15506        return ActivityManager.BROADCAST_SUCCESS;
15507    }
15508
15509    final Intent verifyBroadcastLocked(Intent intent) {
15510        // Refuse possible leaked file descriptors
15511        if (intent != null && intent.hasFileDescriptors() == true) {
15512            throw new IllegalArgumentException("File descriptors passed in Intent");
15513        }
15514
15515        int flags = intent.getFlags();
15516
15517        if (!mProcessesReady) {
15518            // if the caller really truly claims to know what they're doing, go
15519            // ahead and allow the broadcast without launching any receivers
15520            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15521                intent = new Intent(intent);
15522                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15523            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15524                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15525                        + " before boot completion");
15526                throw new IllegalStateException("Cannot broadcast before boot completed");
15527            }
15528        }
15529
15530        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15531            throw new IllegalArgumentException(
15532                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15533        }
15534
15535        return intent;
15536    }
15537
15538    public final int broadcastIntent(IApplicationThread caller,
15539            Intent intent, String resolvedType, IIntentReceiver resultTo,
15540            int resultCode, String resultData, Bundle map,
15541            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15542        enforceNotIsolatedCaller("broadcastIntent");
15543        synchronized(this) {
15544            intent = verifyBroadcastLocked(intent);
15545
15546            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15547            final int callingPid = Binder.getCallingPid();
15548            final int callingUid = Binder.getCallingUid();
15549            final long origId = Binder.clearCallingIdentity();
15550            int res = broadcastIntentLocked(callerApp,
15551                    callerApp != null ? callerApp.info.packageName : null,
15552                    intent, resolvedType, resultTo,
15553                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15554                    callingPid, callingUid, userId);
15555            Binder.restoreCallingIdentity(origId);
15556            return res;
15557        }
15558    }
15559
15560    int broadcastIntentInPackage(String packageName, int uid,
15561            Intent intent, String resolvedType, IIntentReceiver resultTo,
15562            int resultCode, String resultData, Bundle map,
15563            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15564        synchronized(this) {
15565            intent = verifyBroadcastLocked(intent);
15566
15567            final long origId = Binder.clearCallingIdentity();
15568            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15569                    resultTo, resultCode, resultData, map, requiredPermission,
15570                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15571            Binder.restoreCallingIdentity(origId);
15572            return res;
15573        }
15574    }
15575
15576    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15577        // Refuse possible leaked file descriptors
15578        if (intent != null && intent.hasFileDescriptors() == true) {
15579            throw new IllegalArgumentException("File descriptors passed in Intent");
15580        }
15581
15582        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15583                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15584
15585        synchronized(this) {
15586            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15587                    != PackageManager.PERMISSION_GRANTED) {
15588                String msg = "Permission Denial: unbroadcastIntent() from pid="
15589                        + Binder.getCallingPid()
15590                        + ", uid=" + Binder.getCallingUid()
15591                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15592                Slog.w(TAG, msg);
15593                throw new SecurityException(msg);
15594            }
15595            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15596            if (stickies != null) {
15597                ArrayList<Intent> list = stickies.get(intent.getAction());
15598                if (list != null) {
15599                    int N = list.size();
15600                    int i;
15601                    for (i=0; i<N; i++) {
15602                        if (intent.filterEquals(list.get(i))) {
15603                            list.remove(i);
15604                            break;
15605                        }
15606                    }
15607                    if (list.size() <= 0) {
15608                        stickies.remove(intent.getAction());
15609                    }
15610                }
15611                if (stickies.size() <= 0) {
15612                    mStickyBroadcasts.remove(userId);
15613                }
15614            }
15615        }
15616    }
15617
15618    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15619            String resultData, Bundle resultExtras, boolean resultAbort) {
15620        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15621        if (r == null) {
15622            Slog.w(TAG, "finishReceiver called but not found on queue");
15623            return false;
15624        }
15625
15626        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15627    }
15628
15629    void backgroundServicesFinishedLocked(int userId) {
15630        for (BroadcastQueue queue : mBroadcastQueues) {
15631            queue.backgroundServicesFinishedLocked(userId);
15632        }
15633    }
15634
15635    public void finishReceiver(IBinder who, int resultCode, String resultData,
15636            Bundle resultExtras, boolean resultAbort) {
15637        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15638
15639        // Refuse possible leaked file descriptors
15640        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15641            throw new IllegalArgumentException("File descriptors passed in Bundle");
15642        }
15643
15644        final long origId = Binder.clearCallingIdentity();
15645        try {
15646            boolean doNext = false;
15647            BroadcastRecord r;
15648
15649            synchronized(this) {
15650                r = broadcastRecordForReceiverLocked(who);
15651                if (r != null) {
15652                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15653                        resultData, resultExtras, resultAbort, true);
15654                }
15655            }
15656
15657            if (doNext) {
15658                r.queue.processNextBroadcast(false);
15659            }
15660            trimApplications();
15661        } finally {
15662            Binder.restoreCallingIdentity(origId);
15663        }
15664    }
15665
15666    // =========================================================
15667    // INSTRUMENTATION
15668    // =========================================================
15669
15670    public boolean startInstrumentation(ComponentName className,
15671            String profileFile, int flags, Bundle arguments,
15672            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15673            int userId, String abiOverride) {
15674        enforceNotIsolatedCaller("startInstrumentation");
15675        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15676                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15677        // Refuse possible leaked file descriptors
15678        if (arguments != null && arguments.hasFileDescriptors()) {
15679            throw new IllegalArgumentException("File descriptors passed in Bundle");
15680        }
15681
15682        synchronized(this) {
15683            InstrumentationInfo ii = null;
15684            ApplicationInfo ai = null;
15685            try {
15686                ii = mContext.getPackageManager().getInstrumentationInfo(
15687                    className, STOCK_PM_FLAGS);
15688                ai = AppGlobals.getPackageManager().getApplicationInfo(
15689                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15690            } catch (PackageManager.NameNotFoundException e) {
15691            } catch (RemoteException e) {
15692            }
15693            if (ii == null) {
15694                reportStartInstrumentationFailure(watcher, className,
15695                        "Unable to find instrumentation info for: " + className);
15696                return false;
15697            }
15698            if (ai == null) {
15699                reportStartInstrumentationFailure(watcher, className,
15700                        "Unable to find instrumentation target package: " + ii.targetPackage);
15701                return false;
15702            }
15703
15704            int match = mContext.getPackageManager().checkSignatures(
15705                    ii.targetPackage, ii.packageName);
15706            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15707                String msg = "Permission Denial: starting instrumentation "
15708                        + className + " from pid="
15709                        + Binder.getCallingPid()
15710                        + ", uid=" + Binder.getCallingPid()
15711                        + " not allowed because package " + ii.packageName
15712                        + " does not have a signature matching the target "
15713                        + ii.targetPackage;
15714                reportStartInstrumentationFailure(watcher, className, msg);
15715                throw new SecurityException(msg);
15716            }
15717
15718            final long origId = Binder.clearCallingIdentity();
15719            // Instrumentation can kill and relaunch even persistent processes
15720            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15721                    "start instr");
15722            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15723            app.instrumentationClass = className;
15724            app.instrumentationInfo = ai;
15725            app.instrumentationProfileFile = profileFile;
15726            app.instrumentationArguments = arguments;
15727            app.instrumentationWatcher = watcher;
15728            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15729            app.instrumentationResultClass = className;
15730            Binder.restoreCallingIdentity(origId);
15731        }
15732
15733        return true;
15734    }
15735
15736    /**
15737     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15738     * error to the logs, but if somebody is watching, send the report there too.  This enables
15739     * the "am" command to report errors with more information.
15740     *
15741     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15742     * @param cn The component name of the instrumentation.
15743     * @param report The error report.
15744     */
15745    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15746            ComponentName cn, String report) {
15747        Slog.w(TAG, report);
15748        try {
15749            if (watcher != null) {
15750                Bundle results = new Bundle();
15751                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15752                results.putString("Error", report);
15753                watcher.instrumentationStatus(cn, -1, results);
15754            }
15755        } catch (RemoteException e) {
15756            Slog.w(TAG, e);
15757        }
15758    }
15759
15760    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15761        if (app.instrumentationWatcher != null) {
15762            try {
15763                // NOTE:  IInstrumentationWatcher *must* be oneway here
15764                app.instrumentationWatcher.instrumentationFinished(
15765                    app.instrumentationClass,
15766                    resultCode,
15767                    results);
15768            } catch (RemoteException e) {
15769            }
15770        }
15771        if (app.instrumentationUiAutomationConnection != null) {
15772            try {
15773                app.instrumentationUiAutomationConnection.shutdown();
15774            } catch (RemoteException re) {
15775                /* ignore */
15776            }
15777            // Only a UiAutomation can set this flag and now that
15778            // it is finished we make sure it is reset to its default.
15779            mUserIsMonkey = false;
15780        }
15781        app.instrumentationWatcher = null;
15782        app.instrumentationUiAutomationConnection = null;
15783        app.instrumentationClass = null;
15784        app.instrumentationInfo = null;
15785        app.instrumentationProfileFile = null;
15786        app.instrumentationArguments = null;
15787
15788        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15789                "finished inst");
15790    }
15791
15792    public void finishInstrumentation(IApplicationThread target,
15793            int resultCode, Bundle results) {
15794        int userId = UserHandle.getCallingUserId();
15795        // Refuse possible leaked file descriptors
15796        if (results != null && results.hasFileDescriptors()) {
15797            throw new IllegalArgumentException("File descriptors passed in Intent");
15798        }
15799
15800        synchronized(this) {
15801            ProcessRecord app = getRecordForAppLocked(target);
15802            if (app == null) {
15803                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15804                return;
15805            }
15806            final long origId = Binder.clearCallingIdentity();
15807            finishInstrumentationLocked(app, resultCode, results);
15808            Binder.restoreCallingIdentity(origId);
15809        }
15810    }
15811
15812    // =========================================================
15813    // CONFIGURATION
15814    // =========================================================
15815
15816    public ConfigurationInfo getDeviceConfigurationInfo() {
15817        ConfigurationInfo config = new ConfigurationInfo();
15818        synchronized (this) {
15819            config.reqTouchScreen = mConfiguration.touchscreen;
15820            config.reqKeyboardType = mConfiguration.keyboard;
15821            config.reqNavigation = mConfiguration.navigation;
15822            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15823                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15824                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15825            }
15826            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15827                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15828                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15829            }
15830            config.reqGlEsVersion = GL_ES_VERSION;
15831        }
15832        return config;
15833    }
15834
15835    ActivityStack getFocusedStack() {
15836        return mStackSupervisor.getFocusedStack();
15837    }
15838
15839    public Configuration getConfiguration() {
15840        Configuration ci;
15841        synchronized(this) {
15842            ci = new Configuration(mConfiguration);
15843        }
15844        return ci;
15845    }
15846
15847    public void updatePersistentConfiguration(Configuration values) {
15848        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15849                "updateConfiguration()");
15850        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15851                "updateConfiguration()");
15852        if (values == null) {
15853            throw new NullPointerException("Configuration must not be null");
15854        }
15855
15856        synchronized(this) {
15857            final long origId = Binder.clearCallingIdentity();
15858            updateConfigurationLocked(values, null, true, false);
15859            Binder.restoreCallingIdentity(origId);
15860        }
15861    }
15862
15863    public void updateConfiguration(Configuration values) {
15864        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15865                "updateConfiguration()");
15866
15867        synchronized(this) {
15868            if (values == null && mWindowManager != null) {
15869                // sentinel: fetch the current configuration from the window manager
15870                values = mWindowManager.computeNewConfiguration();
15871            }
15872
15873            if (mWindowManager != null) {
15874                mProcessList.applyDisplaySize(mWindowManager);
15875            }
15876
15877            final long origId = Binder.clearCallingIdentity();
15878            if (values != null) {
15879                Settings.System.clearConfiguration(values);
15880            }
15881            updateConfigurationLocked(values, null, false, false);
15882            Binder.restoreCallingIdentity(origId);
15883        }
15884    }
15885
15886    /**
15887     * Do either or both things: (1) change the current configuration, and (2)
15888     * make sure the given activity is running with the (now) current
15889     * configuration.  Returns true if the activity has been left running, or
15890     * false if <var>starting</var> is being destroyed to match the new
15891     * configuration.
15892     * @param persistent TODO
15893     */
15894    boolean updateConfigurationLocked(Configuration values,
15895            ActivityRecord starting, boolean persistent, boolean initLocale) {
15896        int changes = 0;
15897
15898        if (values != null) {
15899            Configuration newConfig = new Configuration(mConfiguration);
15900            changes = newConfig.updateFrom(values);
15901            if (changes != 0) {
15902                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15903                    Slog.i(TAG, "Updating configuration to: " + values);
15904                }
15905
15906                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15907
15908                if (values.locale != null && !initLocale) {
15909                    saveLocaleLocked(values.locale,
15910                                     !values.locale.equals(mConfiguration.locale),
15911                                     values.userSetLocale);
15912                }
15913
15914                mConfigurationSeq++;
15915                if (mConfigurationSeq <= 0) {
15916                    mConfigurationSeq = 1;
15917                }
15918                newConfig.seq = mConfigurationSeq;
15919                mConfiguration = newConfig;
15920                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15921                //mUsageStatsService.noteStartConfig(newConfig);
15922
15923                final Configuration configCopy = new Configuration(mConfiguration);
15924
15925                // TODO: If our config changes, should we auto dismiss any currently
15926                // showing dialogs?
15927                mShowDialogs = shouldShowDialogs(newConfig);
15928
15929                AttributeCache ac = AttributeCache.instance();
15930                if (ac != null) {
15931                    ac.updateConfiguration(configCopy);
15932                }
15933
15934                // Make sure all resources in our process are updated
15935                // right now, so that anyone who is going to retrieve
15936                // resource values after we return will be sure to get
15937                // the new ones.  This is especially important during
15938                // boot, where the first config change needs to guarantee
15939                // all resources have that config before following boot
15940                // code is executed.
15941                mSystemThread.applyConfigurationToResources(configCopy);
15942
15943                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15944                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15945                    msg.obj = new Configuration(configCopy);
15946                    mHandler.sendMessage(msg);
15947                }
15948
15949                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15950                    ProcessRecord app = mLruProcesses.get(i);
15951                    try {
15952                        if (app.thread != null) {
15953                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15954                                    + app.processName + " new config " + mConfiguration);
15955                            app.thread.scheduleConfigurationChanged(configCopy);
15956                        }
15957                    } catch (Exception e) {
15958                    }
15959                }
15960                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15961                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15962                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15963                        | Intent.FLAG_RECEIVER_FOREGROUND);
15964                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15965                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15966                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15967                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15968                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15969                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15970                    broadcastIntentLocked(null, null, intent,
15971                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15972                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15973                }
15974            }
15975        }
15976
15977        boolean kept = true;
15978        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15979        // mainStack is null during startup.
15980        if (mainStack != null) {
15981            if (changes != 0 && starting == null) {
15982                // If the configuration changed, and the caller is not already
15983                // in the process of starting an activity, then find the top
15984                // activity to check if its configuration needs to change.
15985                starting = mainStack.topRunningActivityLocked(null);
15986            }
15987
15988            if (starting != null) {
15989                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15990                // And we need to make sure at this point that all other activities
15991                // are made visible with the correct configuration.
15992                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15993            }
15994        }
15995
15996        if (values != null && mWindowManager != null) {
15997            mWindowManager.setNewConfiguration(mConfiguration);
15998        }
15999
16000        return kept;
16001    }
16002
16003    /**
16004     * Decide based on the configuration whether we should shouw the ANR,
16005     * crash, etc dialogs.  The idea is that if there is no affordnace to
16006     * press the on-screen buttons, we shouldn't show the dialog.
16007     *
16008     * A thought: SystemUI might also want to get told about this, the Power
16009     * dialog / global actions also might want different behaviors.
16010     */
16011    private static final boolean shouldShowDialogs(Configuration config) {
16012        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
16013                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
16014    }
16015
16016    /**
16017     * Save the locale.  You must be inside a synchronized (this) block.
16018     */
16019    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
16020        if(isDiff) {
16021            SystemProperties.set("user.language", l.getLanguage());
16022            SystemProperties.set("user.region", l.getCountry());
16023        }
16024
16025        if(isPersist) {
16026            SystemProperties.set("persist.sys.language", l.getLanguage());
16027            SystemProperties.set("persist.sys.country", l.getCountry());
16028            SystemProperties.set("persist.sys.localevar", l.getVariant());
16029        }
16030    }
16031
16032    @Override
16033    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16034        synchronized (this) {
16035            ActivityRecord srec = ActivityRecord.forToken(token);
16036            if (srec.task != null && srec.task.stack != null) {
16037                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16038            }
16039        }
16040        return false;
16041    }
16042
16043    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16044            Intent resultData) {
16045
16046        synchronized (this) {
16047            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16048            if (stack != null) {
16049                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16050            }
16051            return false;
16052        }
16053    }
16054
16055    public int getLaunchedFromUid(IBinder activityToken) {
16056        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16057        if (srec == null) {
16058            return -1;
16059        }
16060        return srec.launchedFromUid;
16061    }
16062
16063    public String getLaunchedFromPackage(IBinder activityToken) {
16064        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16065        if (srec == null) {
16066            return null;
16067        }
16068        return srec.launchedFromPackage;
16069    }
16070
16071    // =========================================================
16072    // LIFETIME MANAGEMENT
16073    // =========================================================
16074
16075    // Returns which broadcast queue the app is the current [or imminent] receiver
16076    // on, or 'null' if the app is not an active broadcast recipient.
16077    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16078        BroadcastRecord r = app.curReceiver;
16079        if (r != null) {
16080            return r.queue;
16081        }
16082
16083        // It's not the current receiver, but it might be starting up to become one
16084        synchronized (this) {
16085            for (BroadcastQueue queue : mBroadcastQueues) {
16086                r = queue.mPendingBroadcast;
16087                if (r != null && r.curApp == app) {
16088                    // found it; report which queue it's in
16089                    return queue;
16090                }
16091            }
16092        }
16093
16094        return null;
16095    }
16096
16097    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16098            boolean doingAll, long now) {
16099        if (mAdjSeq == app.adjSeq) {
16100            // This adjustment has already been computed.
16101            return app.curRawAdj;
16102        }
16103
16104        if (app.thread == null) {
16105            app.adjSeq = mAdjSeq;
16106            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16107            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16108            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16109        }
16110
16111        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16112        app.adjSource = null;
16113        app.adjTarget = null;
16114        app.empty = false;
16115        app.cached = false;
16116
16117        final int activitiesSize = app.activities.size();
16118
16119        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16120            // The max adjustment doesn't allow this app to be anything
16121            // below foreground, so it is not worth doing work for it.
16122            app.adjType = "fixed";
16123            app.adjSeq = mAdjSeq;
16124            app.curRawAdj = app.maxAdj;
16125            app.foregroundActivities = false;
16126            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16127            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16128            // System processes can do UI, and when they do we want to have
16129            // them trim their memory after the user leaves the UI.  To
16130            // facilitate this, here we need to determine whether or not it
16131            // is currently showing UI.
16132            app.systemNoUi = true;
16133            if (app == TOP_APP) {
16134                app.systemNoUi = false;
16135            } else if (activitiesSize > 0) {
16136                for (int j = 0; j < activitiesSize; j++) {
16137                    final ActivityRecord r = app.activities.get(j);
16138                    if (r.visible) {
16139                        app.systemNoUi = false;
16140                    }
16141                }
16142            }
16143            if (!app.systemNoUi) {
16144                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16145            }
16146            return (app.curAdj=app.maxAdj);
16147        }
16148
16149        app.systemNoUi = false;
16150
16151        // Determine the importance of the process, starting with most
16152        // important to least, and assign an appropriate OOM adjustment.
16153        int adj;
16154        int schedGroup;
16155        int procState;
16156        boolean foregroundActivities = false;
16157        BroadcastQueue queue;
16158        if (app == TOP_APP) {
16159            // The last app on the list is the foreground app.
16160            adj = ProcessList.FOREGROUND_APP_ADJ;
16161            schedGroup = Process.THREAD_GROUP_DEFAULT;
16162            app.adjType = "top-activity";
16163            foregroundActivities = true;
16164            procState = ActivityManager.PROCESS_STATE_TOP;
16165        } else if (app.instrumentationClass != null) {
16166            // Don't want to kill running instrumentation.
16167            adj = ProcessList.FOREGROUND_APP_ADJ;
16168            schedGroup = Process.THREAD_GROUP_DEFAULT;
16169            app.adjType = "instrumentation";
16170            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16171        } else if ((queue = isReceivingBroadcast(app)) != null) {
16172            // An app that is currently receiving a broadcast also
16173            // counts as being in the foreground for OOM killer purposes.
16174            // It's placed in a sched group based on the nature of the
16175            // broadcast as reflected by which queue it's active in.
16176            adj = ProcessList.FOREGROUND_APP_ADJ;
16177            schedGroup = (queue == mFgBroadcastQueue)
16178                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16179            app.adjType = "broadcast";
16180            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16181        } else if (app.executingServices.size() > 0) {
16182            // An app that is currently executing a service callback also
16183            // counts as being in the foreground.
16184            adj = ProcessList.FOREGROUND_APP_ADJ;
16185            schedGroup = app.execServicesFg ?
16186                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16187            app.adjType = "exec-service";
16188            procState = ActivityManager.PROCESS_STATE_SERVICE;
16189            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16190        } else {
16191            // As far as we know the process is empty.  We may change our mind later.
16192            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16193            // At this point we don't actually know the adjustment.  Use the cached adj
16194            // value that the caller wants us to.
16195            adj = cachedAdj;
16196            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16197            app.cached = true;
16198            app.empty = true;
16199            app.adjType = "cch-empty";
16200        }
16201
16202        // Examine all activities if not already foreground.
16203        if (!foregroundActivities && activitiesSize > 0) {
16204            for (int j = 0; j < activitiesSize; j++) {
16205                final ActivityRecord r = app.activities.get(j);
16206                if (r.app != app) {
16207                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16208                            + app + "?!?");
16209                    continue;
16210                }
16211                if (r.visible) {
16212                    // App has a visible activity; only upgrade adjustment.
16213                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16214                        adj = ProcessList.VISIBLE_APP_ADJ;
16215                        app.adjType = "visible";
16216                    }
16217                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16218                        procState = ActivityManager.PROCESS_STATE_TOP;
16219                    }
16220                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16221                    app.cached = false;
16222                    app.empty = false;
16223                    foregroundActivities = true;
16224                    break;
16225                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16226                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16227                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16228                        app.adjType = "pausing";
16229                    }
16230                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16231                        procState = ActivityManager.PROCESS_STATE_TOP;
16232                    }
16233                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16234                    app.cached = false;
16235                    app.empty = false;
16236                    foregroundActivities = true;
16237                } else if (r.state == ActivityState.STOPPING) {
16238                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16239                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16240                        app.adjType = "stopping";
16241                    }
16242                    // For the process state, we will at this point consider the
16243                    // process to be cached.  It will be cached either as an activity
16244                    // or empty depending on whether the activity is finishing.  We do
16245                    // this so that we can treat the process as cached for purposes of
16246                    // memory trimming (determing current memory level, trim command to
16247                    // send to process) since there can be an arbitrary number of stopping
16248                    // processes and they should soon all go into the cached state.
16249                    if (!r.finishing) {
16250                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16251                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16252                        }
16253                    }
16254                    app.cached = false;
16255                    app.empty = false;
16256                    foregroundActivities = true;
16257                } else {
16258                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16259                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16260                        app.adjType = "cch-act";
16261                    }
16262                }
16263            }
16264        }
16265
16266        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16267            if (app.foregroundServices) {
16268                // The user is aware of this app, so make it visible.
16269                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16270                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16271                app.cached = false;
16272                app.adjType = "fg-service";
16273                schedGroup = Process.THREAD_GROUP_DEFAULT;
16274            } else if (app.forcingToForeground != null) {
16275                // The user is aware of this app, so make it visible.
16276                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16277                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16278                app.cached = false;
16279                app.adjType = "force-fg";
16280                app.adjSource = app.forcingToForeground;
16281                schedGroup = Process.THREAD_GROUP_DEFAULT;
16282            }
16283        }
16284
16285        if (app == mHeavyWeightProcess) {
16286            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16287                // We don't want to kill the current heavy-weight process.
16288                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16289                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16290                app.cached = false;
16291                app.adjType = "heavy";
16292            }
16293            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16294                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16295            }
16296        }
16297
16298        if (app == mHomeProcess) {
16299            if (adj > ProcessList.HOME_APP_ADJ) {
16300                // This process is hosting what we currently consider to be the
16301                // home app, so we don't want to let it go into the background.
16302                adj = ProcessList.HOME_APP_ADJ;
16303                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16304                app.cached = false;
16305                app.adjType = "home";
16306            }
16307            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16308                procState = ActivityManager.PROCESS_STATE_HOME;
16309            }
16310        }
16311
16312        if (app == mPreviousProcess && app.activities.size() > 0) {
16313            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16314                // This was the previous process that showed UI to the user.
16315                // We want to try to keep it around more aggressively, to give
16316                // a good experience around switching between two apps.
16317                adj = ProcessList.PREVIOUS_APP_ADJ;
16318                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16319                app.cached = false;
16320                app.adjType = "previous";
16321            }
16322            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16323                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16324            }
16325        }
16326
16327        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16328                + " reason=" + app.adjType);
16329
16330        // By default, we use the computed adjustment.  It may be changed if
16331        // there are applications dependent on our services or providers, but
16332        // this gives us a baseline and makes sure we don't get into an
16333        // infinite recursion.
16334        app.adjSeq = mAdjSeq;
16335        app.curRawAdj = adj;
16336        app.hasStartedServices = false;
16337
16338        if (mBackupTarget != null && app == mBackupTarget.app) {
16339            // If possible we want to avoid killing apps while they're being backed up
16340            if (adj > ProcessList.BACKUP_APP_ADJ) {
16341                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16342                adj = ProcessList.BACKUP_APP_ADJ;
16343                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16344                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16345                }
16346                app.adjType = "backup";
16347                app.cached = false;
16348            }
16349            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16350                procState = ActivityManager.PROCESS_STATE_BACKUP;
16351            }
16352        }
16353
16354        boolean mayBeTop = false;
16355
16356        for (int is = app.services.size()-1;
16357                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16358                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16359                        || procState > ActivityManager.PROCESS_STATE_TOP);
16360                is--) {
16361            ServiceRecord s = app.services.valueAt(is);
16362            if (s.startRequested) {
16363                app.hasStartedServices = true;
16364                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16365                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16366                }
16367                if (app.hasShownUi && app != mHomeProcess) {
16368                    // If this process has shown some UI, let it immediately
16369                    // go to the LRU list because it may be pretty heavy with
16370                    // UI stuff.  We'll tag it with a label just to help
16371                    // debug and understand what is going on.
16372                    if (adj > ProcessList.SERVICE_ADJ) {
16373                        app.adjType = "cch-started-ui-services";
16374                    }
16375                } else {
16376                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16377                        // This service has seen some activity within
16378                        // recent memory, so we will keep its process ahead
16379                        // of the background processes.
16380                        if (adj > ProcessList.SERVICE_ADJ) {
16381                            adj = ProcessList.SERVICE_ADJ;
16382                            app.adjType = "started-services";
16383                            app.cached = false;
16384                        }
16385                    }
16386                    // If we have let the service slide into the background
16387                    // state, still have some text describing what it is doing
16388                    // even though the service no longer has an impact.
16389                    if (adj > ProcessList.SERVICE_ADJ) {
16390                        app.adjType = "cch-started-services";
16391                    }
16392                }
16393            }
16394            for (int conni = s.connections.size()-1;
16395                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16396                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16397                            || procState > ActivityManager.PROCESS_STATE_TOP);
16398                    conni--) {
16399                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16400                for (int i = 0;
16401                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16402                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16403                                || procState > ActivityManager.PROCESS_STATE_TOP);
16404                        i++) {
16405                    // XXX should compute this based on the max of
16406                    // all connected clients.
16407                    ConnectionRecord cr = clist.get(i);
16408                    if (cr.binding.client == app) {
16409                        // Binding to ourself is not interesting.
16410                        continue;
16411                    }
16412                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16413                        ProcessRecord client = cr.binding.client;
16414                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16415                                TOP_APP, doingAll, now);
16416                        int clientProcState = client.curProcState;
16417                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16418                            // If the other app is cached for any reason, for purposes here
16419                            // we are going to consider it empty.  The specific cached state
16420                            // doesn't propagate except under certain conditions.
16421                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16422                        }
16423                        String adjType = null;
16424                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16425                            // Not doing bind OOM management, so treat
16426                            // this guy more like a started service.
16427                            if (app.hasShownUi && app != mHomeProcess) {
16428                                // If this process has shown some UI, let it immediately
16429                                // go to the LRU list because it may be pretty heavy with
16430                                // UI stuff.  We'll tag it with a label just to help
16431                                // debug and understand what is going on.
16432                                if (adj > clientAdj) {
16433                                    adjType = "cch-bound-ui-services";
16434                                }
16435                                app.cached = false;
16436                                clientAdj = adj;
16437                                clientProcState = procState;
16438                            } else {
16439                                if (now >= (s.lastActivity
16440                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16441                                    // This service has not seen activity within
16442                                    // recent memory, so allow it to drop to the
16443                                    // LRU list if there is no other reason to keep
16444                                    // it around.  We'll also tag it with a label just
16445                                    // to help debug and undertand what is going on.
16446                                    if (adj > clientAdj) {
16447                                        adjType = "cch-bound-services";
16448                                    }
16449                                    clientAdj = adj;
16450                                }
16451                            }
16452                        }
16453                        if (adj > clientAdj) {
16454                            // If this process has recently shown UI, and
16455                            // the process that is binding to it is less
16456                            // important than being visible, then we don't
16457                            // care about the binding as much as we care
16458                            // about letting this process get into the LRU
16459                            // list to be killed and restarted if needed for
16460                            // memory.
16461                            if (app.hasShownUi && app != mHomeProcess
16462                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16463                                adjType = "cch-bound-ui-services";
16464                            } else {
16465                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16466                                        |Context.BIND_IMPORTANT)) != 0) {
16467                                    adj = clientAdj;
16468                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16469                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16470                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16471                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16472                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16473                                    adj = clientAdj;
16474                                } else {
16475                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16476                                        adj = ProcessList.VISIBLE_APP_ADJ;
16477                                    }
16478                                }
16479                                if (!client.cached) {
16480                                    app.cached = false;
16481                                }
16482                                adjType = "service";
16483                            }
16484                        }
16485                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16486                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16487                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16488                            }
16489                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16490                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16491                                    // Special handling of clients who are in the top state.
16492                                    // We *may* want to consider this process to be in the
16493                                    // top state as well, but only if there is not another
16494                                    // reason for it to be running.  Being on the top is a
16495                                    // special state, meaning you are specifically running
16496                                    // for the current top app.  If the process is already
16497                                    // running in the background for some other reason, it
16498                                    // is more important to continue considering it to be
16499                                    // in the background state.
16500                                    mayBeTop = true;
16501                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16502                                } else {
16503                                    // Special handling for above-top states (persistent
16504                                    // processes).  These should not bring the current process
16505                                    // into the top state, since they are not on top.  Instead
16506                                    // give them the best state after that.
16507                                    clientProcState =
16508                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16509                                }
16510                            }
16511                        } else {
16512                            if (clientProcState <
16513                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16514                                clientProcState =
16515                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16516                            }
16517                        }
16518                        if (procState > clientProcState) {
16519                            procState = clientProcState;
16520                        }
16521                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16522                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16523                            app.pendingUiClean = true;
16524                        }
16525                        if (adjType != null) {
16526                            app.adjType = adjType;
16527                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16528                                    .REASON_SERVICE_IN_USE;
16529                            app.adjSource = cr.binding.client;
16530                            app.adjSourceProcState = clientProcState;
16531                            app.adjTarget = s.name;
16532                        }
16533                    }
16534                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16535                        app.treatLikeActivity = true;
16536                    }
16537                    final ActivityRecord a = cr.activity;
16538                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16539                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16540                                (a.visible || a.state == ActivityState.RESUMED
16541                                 || a.state == ActivityState.PAUSING)) {
16542                            adj = ProcessList.FOREGROUND_APP_ADJ;
16543                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16544                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16545                            }
16546                            app.cached = false;
16547                            app.adjType = "service";
16548                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16549                                    .REASON_SERVICE_IN_USE;
16550                            app.adjSource = a;
16551                            app.adjSourceProcState = procState;
16552                            app.adjTarget = s.name;
16553                        }
16554                    }
16555                }
16556            }
16557        }
16558
16559        for (int provi = app.pubProviders.size()-1;
16560                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16561                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16562                        || procState > ActivityManager.PROCESS_STATE_TOP);
16563                provi--) {
16564            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16565            for (int i = cpr.connections.size()-1;
16566                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16567                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16568                            || procState > ActivityManager.PROCESS_STATE_TOP);
16569                    i--) {
16570                ContentProviderConnection conn = cpr.connections.get(i);
16571                ProcessRecord client = conn.client;
16572                if (client == app) {
16573                    // Being our own client is not interesting.
16574                    continue;
16575                }
16576                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16577                int clientProcState = client.curProcState;
16578                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16579                    // If the other app is cached for any reason, for purposes here
16580                    // we are going to consider it empty.
16581                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16582                }
16583                if (adj > clientAdj) {
16584                    if (app.hasShownUi && app != mHomeProcess
16585                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16586                        app.adjType = "cch-ui-provider";
16587                    } else {
16588                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16589                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16590                        app.adjType = "provider";
16591                    }
16592                    app.cached &= client.cached;
16593                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16594                            .REASON_PROVIDER_IN_USE;
16595                    app.adjSource = client;
16596                    app.adjSourceProcState = clientProcState;
16597                    app.adjTarget = cpr.name;
16598                }
16599                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16600                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16601                        // Special handling of clients who are in the top state.
16602                        // We *may* want to consider this process to be in the
16603                        // top state as well, but only if there is not another
16604                        // reason for it to be running.  Being on the top is a
16605                        // special state, meaning you are specifically running
16606                        // for the current top app.  If the process is already
16607                        // running in the background for some other reason, it
16608                        // is more important to continue considering it to be
16609                        // in the background state.
16610                        mayBeTop = true;
16611                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16612                    } else {
16613                        // Special handling for above-top states (persistent
16614                        // processes).  These should not bring the current process
16615                        // into the top state, since they are not on top.  Instead
16616                        // give them the best state after that.
16617                        clientProcState =
16618                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16619                    }
16620                }
16621                if (procState > clientProcState) {
16622                    procState = clientProcState;
16623                }
16624                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16625                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16626                }
16627            }
16628            // If the provider has external (non-framework) process
16629            // dependencies, ensure that its adjustment is at least
16630            // FOREGROUND_APP_ADJ.
16631            if (cpr.hasExternalProcessHandles()) {
16632                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16633                    adj = ProcessList.FOREGROUND_APP_ADJ;
16634                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16635                    app.cached = false;
16636                    app.adjType = "provider";
16637                    app.adjTarget = cpr.name;
16638                }
16639                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16640                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16641                }
16642            }
16643        }
16644
16645        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16646            // A client of one of our services or providers is in the top state.  We
16647            // *may* want to be in the top state, but not if we are already running in
16648            // the background for some other reason.  For the decision here, we are going
16649            // to pick out a few specific states that we want to remain in when a client
16650            // is top (states that tend to be longer-term) and otherwise allow it to go
16651            // to the top state.
16652            switch (procState) {
16653                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16654                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16655                case ActivityManager.PROCESS_STATE_SERVICE:
16656                    // These all are longer-term states, so pull them up to the top
16657                    // of the background states, but not all the way to the top state.
16658                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16659                    break;
16660                default:
16661                    // Otherwise, top is a better choice, so take it.
16662                    procState = ActivityManager.PROCESS_STATE_TOP;
16663                    break;
16664            }
16665        }
16666
16667        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16668            if (app.hasClientActivities) {
16669                // This is a cached process, but with client activities.  Mark it so.
16670                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16671                app.adjType = "cch-client-act";
16672            } else if (app.treatLikeActivity) {
16673                // This is a cached process, but somebody wants us to treat it like it has
16674                // an activity, okay!
16675                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16676                app.adjType = "cch-as-act";
16677            }
16678        }
16679
16680        if (adj == ProcessList.SERVICE_ADJ) {
16681            if (doingAll) {
16682                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16683                mNewNumServiceProcs++;
16684                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16685                if (!app.serviceb) {
16686                    // This service isn't far enough down on the LRU list to
16687                    // normally be a B service, but if we are low on RAM and it
16688                    // is large we want to force it down since we would prefer to
16689                    // keep launcher over it.
16690                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16691                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16692                        app.serviceHighRam = true;
16693                        app.serviceb = true;
16694                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16695                    } else {
16696                        mNewNumAServiceProcs++;
16697                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16698                    }
16699                } else {
16700                    app.serviceHighRam = false;
16701                }
16702            }
16703            if (app.serviceb) {
16704                adj = ProcessList.SERVICE_B_ADJ;
16705            }
16706        }
16707
16708        app.curRawAdj = adj;
16709
16710        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16711        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16712        if (adj > app.maxAdj) {
16713            adj = app.maxAdj;
16714            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16715                schedGroup = Process.THREAD_GROUP_DEFAULT;
16716            }
16717        }
16718
16719        // Do final modification to adj.  Everything we do between here and applying
16720        // the final setAdj must be done in this function, because we will also use
16721        // it when computing the final cached adj later.  Note that we don't need to
16722        // worry about this for max adj above, since max adj will always be used to
16723        // keep it out of the cached vaues.
16724        app.curAdj = app.modifyRawOomAdj(adj);
16725        app.curSchedGroup = schedGroup;
16726        app.curProcState = procState;
16727        app.foregroundActivities = foregroundActivities;
16728
16729        return app.curRawAdj;
16730    }
16731
16732    /**
16733     * Schedule PSS collection of a process.
16734     */
16735    void requestPssLocked(ProcessRecord proc, int procState) {
16736        if (mPendingPssProcesses.contains(proc)) {
16737            return;
16738        }
16739        if (mPendingPssProcesses.size() == 0) {
16740            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16741        }
16742        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16743        proc.pssProcState = procState;
16744        mPendingPssProcesses.add(proc);
16745    }
16746
16747    /**
16748     * Schedule PSS collection of all processes.
16749     */
16750    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16751        if (!always) {
16752            if (now < (mLastFullPssTime +
16753                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16754                return;
16755            }
16756        }
16757        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16758        mLastFullPssTime = now;
16759        mFullPssPending = true;
16760        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16761        mPendingPssProcesses.clear();
16762        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16763            ProcessRecord app = mLruProcesses.get(i);
16764            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16765                app.pssProcState = app.setProcState;
16766                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16767                        isSleeping(), now);
16768                mPendingPssProcesses.add(app);
16769            }
16770        }
16771        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16772    }
16773
16774    /**
16775     * Ask a given process to GC right now.
16776     */
16777    final void performAppGcLocked(ProcessRecord app) {
16778        try {
16779            app.lastRequestedGc = SystemClock.uptimeMillis();
16780            if (app.thread != null) {
16781                if (app.reportLowMemory) {
16782                    app.reportLowMemory = false;
16783                    app.thread.scheduleLowMemory();
16784                } else {
16785                    app.thread.processInBackground();
16786                }
16787            }
16788        } catch (Exception e) {
16789            // whatever.
16790        }
16791    }
16792
16793    /**
16794     * Returns true if things are idle enough to perform GCs.
16795     */
16796    private final boolean canGcNowLocked() {
16797        boolean processingBroadcasts = false;
16798        for (BroadcastQueue q : mBroadcastQueues) {
16799            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16800                processingBroadcasts = true;
16801            }
16802        }
16803        return !processingBroadcasts
16804                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16805    }
16806
16807    /**
16808     * Perform GCs on all processes that are waiting for it, but only
16809     * if things are idle.
16810     */
16811    final void performAppGcsLocked() {
16812        final int N = mProcessesToGc.size();
16813        if (N <= 0) {
16814            return;
16815        }
16816        if (canGcNowLocked()) {
16817            while (mProcessesToGc.size() > 0) {
16818                ProcessRecord proc = mProcessesToGc.remove(0);
16819                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16820                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16821                            <= SystemClock.uptimeMillis()) {
16822                        // To avoid spamming the system, we will GC processes one
16823                        // at a time, waiting a few seconds between each.
16824                        performAppGcLocked(proc);
16825                        scheduleAppGcsLocked();
16826                        return;
16827                    } else {
16828                        // It hasn't been long enough since we last GCed this
16829                        // process...  put it in the list to wait for its time.
16830                        addProcessToGcListLocked(proc);
16831                        break;
16832                    }
16833                }
16834            }
16835
16836            scheduleAppGcsLocked();
16837        }
16838    }
16839
16840    /**
16841     * If all looks good, perform GCs on all processes waiting for them.
16842     */
16843    final void performAppGcsIfAppropriateLocked() {
16844        if (canGcNowLocked()) {
16845            performAppGcsLocked();
16846            return;
16847        }
16848        // Still not idle, wait some more.
16849        scheduleAppGcsLocked();
16850    }
16851
16852    /**
16853     * Schedule the execution of all pending app GCs.
16854     */
16855    final void scheduleAppGcsLocked() {
16856        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16857
16858        if (mProcessesToGc.size() > 0) {
16859            // Schedule a GC for the time to the next process.
16860            ProcessRecord proc = mProcessesToGc.get(0);
16861            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16862
16863            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16864            long now = SystemClock.uptimeMillis();
16865            if (when < (now+GC_TIMEOUT)) {
16866                when = now + GC_TIMEOUT;
16867            }
16868            mHandler.sendMessageAtTime(msg, when);
16869        }
16870    }
16871
16872    /**
16873     * Add a process to the array of processes waiting to be GCed.  Keeps the
16874     * list in sorted order by the last GC time.  The process can't already be
16875     * on the list.
16876     */
16877    final void addProcessToGcListLocked(ProcessRecord proc) {
16878        boolean added = false;
16879        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16880            if (mProcessesToGc.get(i).lastRequestedGc <
16881                    proc.lastRequestedGc) {
16882                added = true;
16883                mProcessesToGc.add(i+1, proc);
16884                break;
16885            }
16886        }
16887        if (!added) {
16888            mProcessesToGc.add(0, proc);
16889        }
16890    }
16891
16892    /**
16893     * Set up to ask a process to GC itself.  This will either do it
16894     * immediately, or put it on the list of processes to gc the next
16895     * time things are idle.
16896     */
16897    final void scheduleAppGcLocked(ProcessRecord app) {
16898        long now = SystemClock.uptimeMillis();
16899        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16900            return;
16901        }
16902        if (!mProcessesToGc.contains(app)) {
16903            addProcessToGcListLocked(app);
16904            scheduleAppGcsLocked();
16905        }
16906    }
16907
16908    final void checkExcessivePowerUsageLocked(boolean doKills) {
16909        updateCpuStatsNow();
16910
16911        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16912        boolean doWakeKills = doKills;
16913        boolean doCpuKills = doKills;
16914        if (mLastPowerCheckRealtime == 0) {
16915            doWakeKills = false;
16916        }
16917        if (mLastPowerCheckUptime == 0) {
16918            doCpuKills = false;
16919        }
16920        if (stats.isScreenOn()) {
16921            doWakeKills = false;
16922        }
16923        final long curRealtime = SystemClock.elapsedRealtime();
16924        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16925        final long curUptime = SystemClock.uptimeMillis();
16926        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16927        mLastPowerCheckRealtime = curRealtime;
16928        mLastPowerCheckUptime = curUptime;
16929        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16930            doWakeKills = false;
16931        }
16932        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16933            doCpuKills = false;
16934        }
16935        int i = mLruProcesses.size();
16936        while (i > 0) {
16937            i--;
16938            ProcessRecord app = mLruProcesses.get(i);
16939            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16940                long wtime;
16941                synchronized (stats) {
16942                    wtime = stats.getProcessWakeTime(app.info.uid,
16943                            app.pid, curRealtime);
16944                }
16945                long wtimeUsed = wtime - app.lastWakeTime;
16946                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16947                if (DEBUG_POWER) {
16948                    StringBuilder sb = new StringBuilder(128);
16949                    sb.append("Wake for ");
16950                    app.toShortString(sb);
16951                    sb.append(": over ");
16952                    TimeUtils.formatDuration(realtimeSince, sb);
16953                    sb.append(" used ");
16954                    TimeUtils.formatDuration(wtimeUsed, sb);
16955                    sb.append(" (");
16956                    sb.append((wtimeUsed*100)/realtimeSince);
16957                    sb.append("%)");
16958                    Slog.i(TAG, sb.toString());
16959                    sb.setLength(0);
16960                    sb.append("CPU for ");
16961                    app.toShortString(sb);
16962                    sb.append(": over ");
16963                    TimeUtils.formatDuration(uptimeSince, sb);
16964                    sb.append(" used ");
16965                    TimeUtils.formatDuration(cputimeUsed, sb);
16966                    sb.append(" (");
16967                    sb.append((cputimeUsed*100)/uptimeSince);
16968                    sb.append("%)");
16969                    Slog.i(TAG, sb.toString());
16970                }
16971                // If a process has held a wake lock for more
16972                // than 50% of the time during this period,
16973                // that sounds bad.  Kill!
16974                if (doWakeKills && realtimeSince > 0
16975                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16976                    synchronized (stats) {
16977                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16978                                realtimeSince, wtimeUsed);
16979                    }
16980                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
16981                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16982                } else if (doCpuKills && uptimeSince > 0
16983                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16984                    synchronized (stats) {
16985                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16986                                uptimeSince, cputimeUsed);
16987                    }
16988                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
16989                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16990                } else {
16991                    app.lastWakeTime = wtime;
16992                    app.lastCpuTime = app.curCpuTime;
16993                }
16994            }
16995        }
16996    }
16997
16998    private final boolean applyOomAdjLocked(ProcessRecord app,
16999            ProcessRecord TOP_APP, boolean doingAll, long now) {
17000        boolean success = true;
17001
17002        if (app.curRawAdj != app.setRawAdj) {
17003            app.setRawAdj = app.curRawAdj;
17004        }
17005
17006        int changes = 0;
17007
17008        if (app.curAdj != app.setAdj) {
17009            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
17010            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
17011                TAG, "Set " + app.pid + " " + app.processName +
17012                " adj " + app.curAdj + ": " + app.adjType);
17013            app.setAdj = app.curAdj;
17014        }
17015
17016        if (app.setSchedGroup != app.curSchedGroup) {
17017            app.setSchedGroup = app.curSchedGroup;
17018            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17019                    "Setting process group of " + app.processName
17020                    + " to " + app.curSchedGroup);
17021            if (app.waitingToKill != null &&
17022                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17023                app.kill(app.waitingToKill, true);
17024                success = false;
17025            } else {
17026                if (true) {
17027                    long oldId = Binder.clearCallingIdentity();
17028                    try {
17029                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17030                    } catch (Exception e) {
17031                        Slog.w(TAG, "Failed setting process group of " + app.pid
17032                                + " to " + app.curSchedGroup);
17033                        e.printStackTrace();
17034                    } finally {
17035                        Binder.restoreCallingIdentity(oldId);
17036                    }
17037                } else {
17038                    if (app.thread != null) {
17039                        try {
17040                            app.thread.setSchedulingGroup(app.curSchedGroup);
17041                        } catch (RemoteException e) {
17042                        }
17043                    }
17044                }
17045                Process.setSwappiness(app.pid,
17046                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17047            }
17048        }
17049        if (app.repForegroundActivities != app.foregroundActivities) {
17050            app.repForegroundActivities = app.foregroundActivities;
17051            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17052        }
17053        if (app.repProcState != app.curProcState) {
17054            app.repProcState = app.curProcState;
17055            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17056            if (app.thread != null) {
17057                try {
17058                    if (false) {
17059                        //RuntimeException h = new RuntimeException("here");
17060                        Slog.i(TAG, "Sending new process state " + app.repProcState
17061                                + " to " + app /*, h*/);
17062                    }
17063                    app.thread.setProcessState(app.repProcState);
17064                } catch (RemoteException e) {
17065                }
17066            }
17067        }
17068        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17069                app.setProcState)) {
17070            app.lastStateTime = now;
17071            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17072                    isSleeping(), now);
17073            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17074                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17075                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17076                    + (app.nextPssTime-now) + ": " + app);
17077        } else {
17078            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17079                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17080                requestPssLocked(app, app.setProcState);
17081                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17082                        isSleeping(), now);
17083            } else if (false && DEBUG_PSS) {
17084                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17085            }
17086        }
17087        if (app.setProcState != app.curProcState) {
17088            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17089                    "Proc state change of " + app.processName
17090                    + " to " + app.curProcState);
17091            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17092            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17093            if (setImportant && !curImportant) {
17094                // This app is no longer something we consider important enough to allow to
17095                // use arbitrary amounts of battery power.  Note
17096                // its current wake lock time to later know to kill it if
17097                // it is not behaving well.
17098                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17099                synchronized (stats) {
17100                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17101                            app.pid, SystemClock.elapsedRealtime());
17102                }
17103                app.lastCpuTime = app.curCpuTime;
17104
17105            }
17106            app.setProcState = app.curProcState;
17107            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17108                app.notCachedSinceIdle = false;
17109            }
17110            if (!doingAll) {
17111                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17112            } else {
17113                app.procStateChanged = true;
17114            }
17115        }
17116
17117        if (changes != 0) {
17118            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17119            int i = mPendingProcessChanges.size()-1;
17120            ProcessChangeItem item = null;
17121            while (i >= 0) {
17122                item = mPendingProcessChanges.get(i);
17123                if (item.pid == app.pid) {
17124                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17125                    break;
17126                }
17127                i--;
17128            }
17129            if (i < 0) {
17130                // No existing item in pending changes; need a new one.
17131                final int NA = mAvailProcessChanges.size();
17132                if (NA > 0) {
17133                    item = mAvailProcessChanges.remove(NA-1);
17134                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17135                } else {
17136                    item = new ProcessChangeItem();
17137                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17138                }
17139                item.changes = 0;
17140                item.pid = app.pid;
17141                item.uid = app.info.uid;
17142                if (mPendingProcessChanges.size() == 0) {
17143                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17144                            "*** Enqueueing dispatch processes changed!");
17145                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17146                }
17147                mPendingProcessChanges.add(item);
17148            }
17149            item.changes |= changes;
17150            item.processState = app.repProcState;
17151            item.foregroundActivities = app.repForegroundActivities;
17152            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17153                    + Integer.toHexString(System.identityHashCode(item))
17154                    + " " + app.toShortString() + ": changes=" + item.changes
17155                    + " procState=" + item.processState
17156                    + " foreground=" + item.foregroundActivities
17157                    + " type=" + app.adjType + " source=" + app.adjSource
17158                    + " target=" + app.adjTarget);
17159        }
17160
17161        return success;
17162    }
17163
17164    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17165        if (proc.thread != null) {
17166            if (proc.baseProcessTracker != null) {
17167                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17168            }
17169            if (proc.repProcState >= 0) {
17170                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17171                        proc.repProcState);
17172            }
17173        }
17174    }
17175
17176    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17177            ProcessRecord TOP_APP, boolean doingAll, long now) {
17178        if (app.thread == null) {
17179            return false;
17180        }
17181
17182        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17183
17184        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17185    }
17186
17187    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17188            boolean oomAdj) {
17189        if (isForeground != proc.foregroundServices) {
17190            proc.foregroundServices = isForeground;
17191            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17192                    proc.info.uid);
17193            if (isForeground) {
17194                if (curProcs == null) {
17195                    curProcs = new ArrayList<ProcessRecord>();
17196                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17197                }
17198                if (!curProcs.contains(proc)) {
17199                    curProcs.add(proc);
17200                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17201                            proc.info.packageName, proc.info.uid);
17202                }
17203            } else {
17204                if (curProcs != null) {
17205                    if (curProcs.remove(proc)) {
17206                        mBatteryStatsService.noteEvent(
17207                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17208                                proc.info.packageName, proc.info.uid);
17209                        if (curProcs.size() <= 0) {
17210                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17211                        }
17212                    }
17213                }
17214            }
17215            if (oomAdj) {
17216                updateOomAdjLocked();
17217            }
17218        }
17219    }
17220
17221    private final ActivityRecord resumedAppLocked() {
17222        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17223        String pkg;
17224        int uid;
17225        if (act != null) {
17226            pkg = act.packageName;
17227            uid = act.info.applicationInfo.uid;
17228        } else {
17229            pkg = null;
17230            uid = -1;
17231        }
17232        // Has the UID or resumed package name changed?
17233        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17234                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17235            if (mCurResumedPackage != null) {
17236                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17237                        mCurResumedPackage, mCurResumedUid);
17238            }
17239            mCurResumedPackage = pkg;
17240            mCurResumedUid = uid;
17241            if (mCurResumedPackage != null) {
17242                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17243                        mCurResumedPackage, mCurResumedUid);
17244            }
17245        }
17246        return act;
17247    }
17248
17249    final boolean updateOomAdjLocked(ProcessRecord app) {
17250        final ActivityRecord TOP_ACT = resumedAppLocked();
17251        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17252        final boolean wasCached = app.cached;
17253
17254        mAdjSeq++;
17255
17256        // This is the desired cached adjusment we want to tell it to use.
17257        // If our app is currently cached, we know it, and that is it.  Otherwise,
17258        // we don't know it yet, and it needs to now be cached we will then
17259        // need to do a complete oom adj.
17260        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17261                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17262        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17263                SystemClock.uptimeMillis());
17264        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17265            // Changed to/from cached state, so apps after it in the LRU
17266            // list may also be changed.
17267            updateOomAdjLocked();
17268        }
17269        return success;
17270    }
17271
17272    final void updateOomAdjLocked() {
17273        final ActivityRecord TOP_ACT = resumedAppLocked();
17274        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17275        final long now = SystemClock.uptimeMillis();
17276        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17277        final int N = mLruProcesses.size();
17278
17279        if (false) {
17280            RuntimeException e = new RuntimeException();
17281            e.fillInStackTrace();
17282            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17283        }
17284
17285        mAdjSeq++;
17286        mNewNumServiceProcs = 0;
17287        mNewNumAServiceProcs = 0;
17288
17289        final int emptyProcessLimit;
17290        final int cachedProcessLimit;
17291        if (mProcessLimit <= 0) {
17292            emptyProcessLimit = cachedProcessLimit = 0;
17293        } else if (mProcessLimit == 1) {
17294            emptyProcessLimit = 1;
17295            cachedProcessLimit = 0;
17296        } else {
17297            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17298            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17299        }
17300
17301        // Let's determine how many processes we have running vs.
17302        // how many slots we have for background processes; we may want
17303        // to put multiple processes in a slot of there are enough of
17304        // them.
17305        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17306                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17307        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17308        if (numEmptyProcs > cachedProcessLimit) {
17309            // If there are more empty processes than our limit on cached
17310            // processes, then use the cached process limit for the factor.
17311            // This ensures that the really old empty processes get pushed
17312            // down to the bottom, so if we are running low on memory we will
17313            // have a better chance at keeping around more cached processes
17314            // instead of a gazillion empty processes.
17315            numEmptyProcs = cachedProcessLimit;
17316        }
17317        int emptyFactor = numEmptyProcs/numSlots;
17318        if (emptyFactor < 1) emptyFactor = 1;
17319        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17320        if (cachedFactor < 1) cachedFactor = 1;
17321        int stepCached = 0;
17322        int stepEmpty = 0;
17323        int numCached = 0;
17324        int numEmpty = 0;
17325        int numTrimming = 0;
17326
17327        mNumNonCachedProcs = 0;
17328        mNumCachedHiddenProcs = 0;
17329
17330        // First update the OOM adjustment for each of the
17331        // application processes based on their current state.
17332        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17333        int nextCachedAdj = curCachedAdj+1;
17334        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17335        int nextEmptyAdj = curEmptyAdj+2;
17336        for (int i=N-1; i>=0; i--) {
17337            ProcessRecord app = mLruProcesses.get(i);
17338            if (!app.killedByAm && app.thread != null) {
17339                app.procStateChanged = false;
17340                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17341
17342                // If we haven't yet assigned the final cached adj
17343                // to the process, do that now.
17344                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17345                    switch (app.curProcState) {
17346                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17347                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17348                            // This process is a cached process holding activities...
17349                            // assign it the next cached value for that type, and then
17350                            // step that cached level.
17351                            app.curRawAdj = curCachedAdj;
17352                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17353                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17354                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17355                                    + ")");
17356                            if (curCachedAdj != nextCachedAdj) {
17357                                stepCached++;
17358                                if (stepCached >= cachedFactor) {
17359                                    stepCached = 0;
17360                                    curCachedAdj = nextCachedAdj;
17361                                    nextCachedAdj += 2;
17362                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17363                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17364                                    }
17365                                }
17366                            }
17367                            break;
17368                        default:
17369                            // For everything else, assign next empty cached process
17370                            // level and bump that up.  Note that this means that
17371                            // long-running services that have dropped down to the
17372                            // cached level will be treated as empty (since their process
17373                            // state is still as a service), which is what we want.
17374                            app.curRawAdj = curEmptyAdj;
17375                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17376                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17377                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17378                                    + ")");
17379                            if (curEmptyAdj != nextEmptyAdj) {
17380                                stepEmpty++;
17381                                if (stepEmpty >= emptyFactor) {
17382                                    stepEmpty = 0;
17383                                    curEmptyAdj = nextEmptyAdj;
17384                                    nextEmptyAdj += 2;
17385                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17386                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17387                                    }
17388                                }
17389                            }
17390                            break;
17391                    }
17392                }
17393
17394                applyOomAdjLocked(app, TOP_APP, true, now);
17395
17396                // Count the number of process types.
17397                switch (app.curProcState) {
17398                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17399                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17400                        mNumCachedHiddenProcs++;
17401                        numCached++;
17402                        if (numCached > cachedProcessLimit) {
17403                            app.kill("cached #" + numCached, true);
17404                        }
17405                        break;
17406                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17407                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17408                                && app.lastActivityTime < oldTime) {
17409                            app.kill("empty for "
17410                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17411                                    / 1000) + "s", true);
17412                        } else {
17413                            numEmpty++;
17414                            if (numEmpty > emptyProcessLimit) {
17415                                app.kill("empty #" + numEmpty, true);
17416                            }
17417                        }
17418                        break;
17419                    default:
17420                        mNumNonCachedProcs++;
17421                        break;
17422                }
17423
17424                if (app.isolated && app.services.size() <= 0) {
17425                    // If this is an isolated process, and there are no
17426                    // services running in it, then the process is no longer
17427                    // needed.  We agressively kill these because we can by
17428                    // definition not re-use the same process again, and it is
17429                    // good to avoid having whatever code was running in them
17430                    // left sitting around after no longer needed.
17431                    app.kill("isolated not needed", true);
17432                }
17433
17434                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17435                        && !app.killedByAm) {
17436                    numTrimming++;
17437                }
17438            }
17439        }
17440
17441        mNumServiceProcs = mNewNumServiceProcs;
17442
17443        // Now determine the memory trimming level of background processes.
17444        // Unfortunately we need to start at the back of the list to do this
17445        // properly.  We only do this if the number of background apps we
17446        // are managing to keep around is less than half the maximum we desire;
17447        // if we are keeping a good number around, we'll let them use whatever
17448        // memory they want.
17449        final int numCachedAndEmpty = numCached + numEmpty;
17450        int memFactor;
17451        if (numCached <= ProcessList.TRIM_CACHED_APPS
17452                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17453            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17454                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17455            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17456                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17457            } else {
17458                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17459            }
17460        } else {
17461            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17462        }
17463        // We always allow the memory level to go up (better).  We only allow it to go
17464        // down if we are in a state where that is allowed, *and* the total number of processes
17465        // has gone down since last time.
17466        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17467                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17468                + " last=" + mLastNumProcesses);
17469        if (memFactor > mLastMemoryLevel) {
17470            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17471                memFactor = mLastMemoryLevel;
17472                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17473            }
17474        }
17475        mLastMemoryLevel = memFactor;
17476        mLastNumProcesses = mLruProcesses.size();
17477        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17478        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17479        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17480            if (mLowRamStartTime == 0) {
17481                mLowRamStartTime = now;
17482            }
17483            int step = 0;
17484            int fgTrimLevel;
17485            switch (memFactor) {
17486                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17487                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17488                    break;
17489                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17490                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17491                    break;
17492                default:
17493                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17494                    break;
17495            }
17496            int factor = numTrimming/3;
17497            int minFactor = 2;
17498            if (mHomeProcess != null) minFactor++;
17499            if (mPreviousProcess != null) minFactor++;
17500            if (factor < minFactor) factor = minFactor;
17501            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17502            for (int i=N-1; i>=0; i--) {
17503                ProcessRecord app = mLruProcesses.get(i);
17504                if (allChanged || app.procStateChanged) {
17505                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17506                    app.procStateChanged = false;
17507                }
17508                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17509                        && !app.killedByAm) {
17510                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17511                        try {
17512                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17513                                    "Trimming memory of " + app.processName
17514                                    + " to " + curLevel);
17515                            app.thread.scheduleTrimMemory(curLevel);
17516                        } catch (RemoteException e) {
17517                        }
17518                        if (false) {
17519                            // For now we won't do this; our memory trimming seems
17520                            // to be good enough at this point that destroying
17521                            // activities causes more harm than good.
17522                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17523                                    && app != mHomeProcess && app != mPreviousProcess) {
17524                                // Need to do this on its own message because the stack may not
17525                                // be in a consistent state at this point.
17526                                // For these apps we will also finish their activities
17527                                // to help them free memory.
17528                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17529                            }
17530                        }
17531                    }
17532                    app.trimMemoryLevel = curLevel;
17533                    step++;
17534                    if (step >= factor) {
17535                        step = 0;
17536                        switch (curLevel) {
17537                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17538                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17539                                break;
17540                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17541                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17542                                break;
17543                        }
17544                    }
17545                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17546                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17547                            && app.thread != null) {
17548                        try {
17549                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17550                                    "Trimming memory of heavy-weight " + app.processName
17551                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17552                            app.thread.scheduleTrimMemory(
17553                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17554                        } catch (RemoteException e) {
17555                        }
17556                    }
17557                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17558                } else {
17559                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17560                            || app.systemNoUi) && app.pendingUiClean) {
17561                        // If this application is now in the background and it
17562                        // had done UI, then give it the special trim level to
17563                        // have it free UI resources.
17564                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17565                        if (app.trimMemoryLevel < level && app.thread != null) {
17566                            try {
17567                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17568                                        "Trimming memory of bg-ui " + app.processName
17569                                        + " to " + level);
17570                                app.thread.scheduleTrimMemory(level);
17571                            } catch (RemoteException e) {
17572                            }
17573                        }
17574                        app.pendingUiClean = false;
17575                    }
17576                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17577                        try {
17578                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17579                                    "Trimming memory of fg " + app.processName
17580                                    + " to " + fgTrimLevel);
17581                            app.thread.scheduleTrimMemory(fgTrimLevel);
17582                        } catch (RemoteException e) {
17583                        }
17584                    }
17585                    app.trimMemoryLevel = fgTrimLevel;
17586                }
17587            }
17588        } else {
17589            if (mLowRamStartTime != 0) {
17590                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17591                mLowRamStartTime = 0;
17592            }
17593            for (int i=N-1; i>=0; i--) {
17594                ProcessRecord app = mLruProcesses.get(i);
17595                if (allChanged || app.procStateChanged) {
17596                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17597                    app.procStateChanged = false;
17598                }
17599                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17600                        || app.systemNoUi) && app.pendingUiClean) {
17601                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17602                            && app.thread != null) {
17603                        try {
17604                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17605                                    "Trimming memory of ui hidden " + app.processName
17606                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17607                            app.thread.scheduleTrimMemory(
17608                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17609                        } catch (RemoteException e) {
17610                        }
17611                    }
17612                    app.pendingUiClean = false;
17613                }
17614                app.trimMemoryLevel = 0;
17615            }
17616        }
17617
17618        if (mAlwaysFinishActivities) {
17619            // Need to do this on its own message because the stack may not
17620            // be in a consistent state at this point.
17621            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17622        }
17623
17624        if (allChanged) {
17625            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17626        }
17627
17628        if (mProcessStats.shouldWriteNowLocked(now)) {
17629            mHandler.post(new Runnable() {
17630                @Override public void run() {
17631                    synchronized (ActivityManagerService.this) {
17632                        mProcessStats.writeStateAsyncLocked();
17633                    }
17634                }
17635            });
17636        }
17637
17638        if (DEBUG_OOM_ADJ) {
17639            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17640        }
17641    }
17642
17643    final void trimApplications() {
17644        synchronized (this) {
17645            int i;
17646
17647            // First remove any unused application processes whose package
17648            // has been removed.
17649            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17650                final ProcessRecord app = mRemovedProcesses.get(i);
17651                if (app.activities.size() == 0
17652                        && app.curReceiver == null && app.services.size() == 0) {
17653                    Slog.i(
17654                        TAG, "Exiting empty application process "
17655                        + app.processName + " ("
17656                        + (app.thread != null ? app.thread.asBinder() : null)
17657                        + ")\n");
17658                    if (app.pid > 0 && app.pid != MY_PID) {
17659                        app.kill("empty", false);
17660                    } else {
17661                        try {
17662                            app.thread.scheduleExit();
17663                        } catch (Exception e) {
17664                            // Ignore exceptions.
17665                        }
17666                    }
17667                    cleanUpApplicationRecordLocked(app, false, true, -1);
17668                    mRemovedProcesses.remove(i);
17669
17670                    if (app.persistent) {
17671                        addAppLocked(app.info, false, null /* ABI override */);
17672                    }
17673                }
17674            }
17675
17676            // Now update the oom adj for all processes.
17677            updateOomAdjLocked();
17678        }
17679    }
17680
17681    /** This method sends the specified signal to each of the persistent apps */
17682    public void signalPersistentProcesses(int sig) throws RemoteException {
17683        if (sig != Process.SIGNAL_USR1) {
17684            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17685        }
17686
17687        synchronized (this) {
17688            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17689                    != PackageManager.PERMISSION_GRANTED) {
17690                throw new SecurityException("Requires permission "
17691                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17692            }
17693
17694            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17695                ProcessRecord r = mLruProcesses.get(i);
17696                if (r.thread != null && r.persistent) {
17697                    Process.sendSignal(r.pid, sig);
17698                }
17699            }
17700        }
17701    }
17702
17703    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17704        if (proc == null || proc == mProfileProc) {
17705            proc = mProfileProc;
17706            profileType = mProfileType;
17707            clearProfilerLocked();
17708        }
17709        if (proc == null) {
17710            return;
17711        }
17712        try {
17713            proc.thread.profilerControl(false, null, profileType);
17714        } catch (RemoteException e) {
17715            throw new IllegalStateException("Process disappeared");
17716        }
17717    }
17718
17719    private void clearProfilerLocked() {
17720        if (mProfileFd != null) {
17721            try {
17722                mProfileFd.close();
17723            } catch (IOException e) {
17724            }
17725        }
17726        mProfileApp = null;
17727        mProfileProc = null;
17728        mProfileFile = null;
17729        mProfileType = 0;
17730        mAutoStopProfiler = false;
17731        mSamplingInterval = 0;
17732    }
17733
17734    public boolean profileControl(String process, int userId, boolean start,
17735            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17736
17737        try {
17738            synchronized (this) {
17739                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17740                // its own permission.
17741                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17742                        != PackageManager.PERMISSION_GRANTED) {
17743                    throw new SecurityException("Requires permission "
17744                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17745                }
17746
17747                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17748                    throw new IllegalArgumentException("null profile info or fd");
17749                }
17750
17751                ProcessRecord proc = null;
17752                if (process != null) {
17753                    proc = findProcessLocked(process, userId, "profileControl");
17754                }
17755
17756                if (start && (proc == null || proc.thread == null)) {
17757                    throw new IllegalArgumentException("Unknown process: " + process);
17758                }
17759
17760                if (start) {
17761                    stopProfilerLocked(null, 0);
17762                    setProfileApp(proc.info, proc.processName, profilerInfo);
17763                    mProfileProc = proc;
17764                    mProfileType = profileType;
17765                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17766                    try {
17767                        fd = fd.dup();
17768                    } catch (IOException e) {
17769                        fd = null;
17770                    }
17771                    profilerInfo.profileFd = fd;
17772                    proc.thread.profilerControl(start, profilerInfo, profileType);
17773                    fd = null;
17774                    mProfileFd = null;
17775                } else {
17776                    stopProfilerLocked(proc, profileType);
17777                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17778                        try {
17779                            profilerInfo.profileFd.close();
17780                        } catch (IOException e) {
17781                        }
17782                    }
17783                }
17784
17785                return true;
17786            }
17787        } catch (RemoteException e) {
17788            throw new IllegalStateException("Process disappeared");
17789        } finally {
17790            if (profilerInfo != null && profilerInfo.profileFd != null) {
17791                try {
17792                    profilerInfo.profileFd.close();
17793                } catch (IOException e) {
17794                }
17795            }
17796        }
17797    }
17798
17799    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17800        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17801                userId, true, ALLOW_FULL_ONLY, callName, null);
17802        ProcessRecord proc = null;
17803        try {
17804            int pid = Integer.parseInt(process);
17805            synchronized (mPidsSelfLocked) {
17806                proc = mPidsSelfLocked.get(pid);
17807            }
17808        } catch (NumberFormatException e) {
17809        }
17810
17811        if (proc == null) {
17812            ArrayMap<String, SparseArray<ProcessRecord>> all
17813                    = mProcessNames.getMap();
17814            SparseArray<ProcessRecord> procs = all.get(process);
17815            if (procs != null && procs.size() > 0) {
17816                proc = procs.valueAt(0);
17817                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17818                    for (int i=1; i<procs.size(); i++) {
17819                        ProcessRecord thisProc = procs.valueAt(i);
17820                        if (thisProc.userId == userId) {
17821                            proc = thisProc;
17822                            break;
17823                        }
17824                    }
17825                }
17826            }
17827        }
17828
17829        return proc;
17830    }
17831
17832    public boolean dumpHeap(String process, int userId, boolean managed,
17833            String path, ParcelFileDescriptor fd) throws RemoteException {
17834
17835        try {
17836            synchronized (this) {
17837                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17838                // its own permission (same as profileControl).
17839                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17840                        != PackageManager.PERMISSION_GRANTED) {
17841                    throw new SecurityException("Requires permission "
17842                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17843                }
17844
17845                if (fd == null) {
17846                    throw new IllegalArgumentException("null fd");
17847                }
17848
17849                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17850                if (proc == null || proc.thread == null) {
17851                    throw new IllegalArgumentException("Unknown process: " + process);
17852                }
17853
17854                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17855                if (!isDebuggable) {
17856                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17857                        throw new SecurityException("Process not debuggable: " + proc);
17858                    }
17859                }
17860
17861                proc.thread.dumpHeap(managed, path, fd);
17862                fd = null;
17863                return true;
17864            }
17865        } catch (RemoteException e) {
17866            throw new IllegalStateException("Process disappeared");
17867        } finally {
17868            if (fd != null) {
17869                try {
17870                    fd.close();
17871                } catch (IOException e) {
17872                }
17873            }
17874        }
17875    }
17876
17877    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17878    public void monitor() {
17879        synchronized (this) { }
17880    }
17881
17882    void onCoreSettingsChange(Bundle settings) {
17883        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17884            ProcessRecord processRecord = mLruProcesses.get(i);
17885            try {
17886                if (processRecord.thread != null) {
17887                    processRecord.thread.setCoreSettings(settings);
17888                }
17889            } catch (RemoteException re) {
17890                /* ignore */
17891            }
17892        }
17893    }
17894
17895    // Multi-user methods
17896
17897    /**
17898     * Start user, if its not already running, but don't bring it to foreground.
17899     */
17900    @Override
17901    public boolean startUserInBackground(final int userId) {
17902        return startUser(userId, /* foreground */ false);
17903    }
17904
17905    /**
17906     * Start user, if its not already running, and bring it to foreground.
17907     */
17908    boolean startUserInForeground(final int userId, Dialog dlg) {
17909        boolean result = startUser(userId, /* foreground */ true);
17910        dlg.dismiss();
17911        return result;
17912    }
17913
17914    /**
17915     * Refreshes the list of users related to the current user when either a
17916     * user switch happens or when a new related user is started in the
17917     * background.
17918     */
17919    private void updateCurrentProfileIdsLocked() {
17920        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17921                mCurrentUserId, false /* enabledOnly */);
17922        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17923        for (int i = 0; i < currentProfileIds.length; i++) {
17924            currentProfileIds[i] = profiles.get(i).id;
17925        }
17926        mCurrentProfileIds = currentProfileIds;
17927
17928        synchronized (mUserProfileGroupIdsSelfLocked) {
17929            mUserProfileGroupIdsSelfLocked.clear();
17930            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17931            for (int i = 0; i < users.size(); i++) {
17932                UserInfo user = users.get(i);
17933                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17934                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17935                }
17936            }
17937        }
17938    }
17939
17940    private Set getProfileIdsLocked(int userId) {
17941        Set userIds = new HashSet<Integer>();
17942        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17943                userId, false /* enabledOnly */);
17944        for (UserInfo user : profiles) {
17945            userIds.add(Integer.valueOf(user.id));
17946        }
17947        return userIds;
17948    }
17949
17950    @Override
17951    public boolean switchUser(final int userId) {
17952        String userName;
17953        synchronized (this) {
17954            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17955            if (userInfo == null) {
17956                Slog.w(TAG, "No user info for user #" + userId);
17957                return false;
17958            }
17959            if (userInfo.isManagedProfile()) {
17960                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17961                return false;
17962            }
17963            userName = userInfo.name;
17964        }
17965        mHandler.removeMessages(START_USER_SWITCH_MSG);
17966        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17967        return true;
17968    }
17969
17970    private void showUserSwitchDialog(int userId, String userName) {
17971        // The dialog will show and then initiate the user switch by calling startUserInForeground
17972        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17973                true /* above system */);
17974        d.show();
17975    }
17976
17977    private boolean startUser(final int userId, final boolean foreground) {
17978        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17979                != PackageManager.PERMISSION_GRANTED) {
17980            String msg = "Permission Denial: switchUser() from pid="
17981                    + Binder.getCallingPid()
17982                    + ", uid=" + Binder.getCallingUid()
17983                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17984            Slog.w(TAG, msg);
17985            throw new SecurityException(msg);
17986        }
17987
17988        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17989
17990        final long ident = Binder.clearCallingIdentity();
17991        try {
17992            synchronized (this) {
17993                final int oldUserId = mCurrentUserId;
17994                if (oldUserId == userId) {
17995                    return true;
17996                }
17997
17998                mStackSupervisor.setLockTaskModeLocked(null, false);
17999
18000                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
18001                if (userInfo == null) {
18002                    Slog.w(TAG, "No user info for user #" + userId);
18003                    return false;
18004                }
18005                if (foreground && userInfo.isManagedProfile()) {
18006                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
18007                    return false;
18008                }
18009
18010                if (foreground) {
18011                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
18012                            R.anim.screen_user_enter);
18013                }
18014
18015                boolean needStart = false;
18016
18017                // If the user we are switching to is not currently started, then
18018                // we need to start it now.
18019                if (mStartedUsers.get(userId) == null) {
18020                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
18021                    updateStartedUserArrayLocked();
18022                    needStart = true;
18023                }
18024
18025                final Integer userIdInt = Integer.valueOf(userId);
18026                mUserLru.remove(userIdInt);
18027                mUserLru.add(userIdInt);
18028
18029                if (foreground) {
18030                    mCurrentUserId = userId;
18031                    updateCurrentProfileIdsLocked();
18032                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18033                    // Once the internal notion of the active user has switched, we lock the device
18034                    // with the option to show the user switcher on the keyguard.
18035                    mWindowManager.lockNow(null);
18036                } else {
18037                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18038                    updateCurrentProfileIdsLocked();
18039                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18040                    mUserLru.remove(currentUserIdInt);
18041                    mUserLru.add(currentUserIdInt);
18042                }
18043
18044                final UserStartedState uss = mStartedUsers.get(userId);
18045
18046                // Make sure user is in the started state.  If it is currently
18047                // stopping, we need to knock that off.
18048                if (uss.mState == UserStartedState.STATE_STOPPING) {
18049                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18050                    // so we can just fairly silently bring the user back from
18051                    // the almost-dead.
18052                    uss.mState = UserStartedState.STATE_RUNNING;
18053                    updateStartedUserArrayLocked();
18054                    needStart = true;
18055                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18056                    // This means ACTION_SHUTDOWN has been sent, so we will
18057                    // need to treat this as a new boot of the user.
18058                    uss.mState = UserStartedState.STATE_BOOTING;
18059                    updateStartedUserArrayLocked();
18060                    needStart = true;
18061                }
18062
18063                if (uss.mState == UserStartedState.STATE_BOOTING) {
18064                    // Booting up a new user, need to tell system services about it.
18065                    // Note that this is on the same handler as scheduling of broadcasts,
18066                    // which is important because it needs to go first.
18067                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18068                }
18069
18070                if (foreground) {
18071                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18072                            oldUserId));
18073                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18074                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18075                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18076                            oldUserId, userId, uss));
18077                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18078                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18079                }
18080
18081                if (needStart) {
18082                    // Send USER_STARTED broadcast
18083                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18084                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18085                            | Intent.FLAG_RECEIVER_FOREGROUND);
18086                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18087                    broadcastIntentLocked(null, null, intent,
18088                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18089                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18090                }
18091
18092                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18093                    if (userId != UserHandle.USER_OWNER) {
18094                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18095                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18096                        broadcastIntentLocked(null, null, intent, null,
18097                                new IIntentReceiver.Stub() {
18098                                    public void performReceive(Intent intent, int resultCode,
18099                                            String data, Bundle extras, boolean ordered,
18100                                            boolean sticky, int sendingUser) {
18101                                        onUserInitialized(uss, foreground, oldUserId, userId);
18102                                    }
18103                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18104                                true, false, MY_PID, Process.SYSTEM_UID,
18105                                userId);
18106                        uss.initializing = true;
18107                    } else {
18108                        getUserManagerLocked().makeInitialized(userInfo.id);
18109                    }
18110                }
18111
18112                if (foreground) {
18113                    if (!uss.initializing) {
18114                        moveUserToForeground(uss, oldUserId, userId);
18115                    }
18116                } else {
18117                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18118                }
18119
18120                if (needStart) {
18121                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18122                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18123                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18124                    broadcastIntentLocked(null, null, intent,
18125                            null, new IIntentReceiver.Stub() {
18126                                @Override
18127                                public void performReceive(Intent intent, int resultCode, String data,
18128                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18129                                        throws RemoteException {
18130                                }
18131                            }, 0, null, null,
18132                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18133                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18134                }
18135            }
18136        } finally {
18137            Binder.restoreCallingIdentity(ident);
18138        }
18139
18140        return true;
18141    }
18142
18143    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18144        long ident = Binder.clearCallingIdentity();
18145        try {
18146            Intent intent;
18147            if (oldUserId >= 0) {
18148                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18149                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18150                int count = profiles.size();
18151                for (int i = 0; i < count; i++) {
18152                    int profileUserId = profiles.get(i).id;
18153                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18154                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18155                            | Intent.FLAG_RECEIVER_FOREGROUND);
18156                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18157                    broadcastIntentLocked(null, null, intent,
18158                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18159                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18160                }
18161            }
18162            if (newUserId >= 0) {
18163                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18164                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18165                int count = profiles.size();
18166                for (int i = 0; i < count; i++) {
18167                    int profileUserId = profiles.get(i).id;
18168                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18169                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18170                            | Intent.FLAG_RECEIVER_FOREGROUND);
18171                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18172                    broadcastIntentLocked(null, null, intent,
18173                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18174                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18175                }
18176                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18177                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18178                        | Intent.FLAG_RECEIVER_FOREGROUND);
18179                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18180                broadcastIntentLocked(null, null, intent,
18181                        null, null, 0, null, null,
18182                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18183                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18184            }
18185        } finally {
18186            Binder.restoreCallingIdentity(ident);
18187        }
18188    }
18189
18190    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18191            final int newUserId) {
18192        final int N = mUserSwitchObservers.beginBroadcast();
18193        if (N > 0) {
18194            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18195                int mCount = 0;
18196                @Override
18197                public void sendResult(Bundle data) throws RemoteException {
18198                    synchronized (ActivityManagerService.this) {
18199                        if (mCurUserSwitchCallback == this) {
18200                            mCount++;
18201                            if (mCount == N) {
18202                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18203                            }
18204                        }
18205                    }
18206                }
18207            };
18208            synchronized (this) {
18209                uss.switching = true;
18210                mCurUserSwitchCallback = callback;
18211            }
18212            for (int i=0; i<N; i++) {
18213                try {
18214                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18215                            newUserId, callback);
18216                } catch (RemoteException e) {
18217                }
18218            }
18219        } else {
18220            synchronized (this) {
18221                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18222            }
18223        }
18224        mUserSwitchObservers.finishBroadcast();
18225    }
18226
18227    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18228        synchronized (this) {
18229            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18230            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18231        }
18232    }
18233
18234    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18235        mCurUserSwitchCallback = null;
18236        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18237        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18238                oldUserId, newUserId, uss));
18239    }
18240
18241    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18242        synchronized (this) {
18243            if (foreground) {
18244                moveUserToForeground(uss, oldUserId, newUserId);
18245            }
18246        }
18247
18248        completeSwitchAndInitalize(uss, newUserId, true, false);
18249    }
18250
18251    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18252        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18253        if (homeInFront) {
18254            startHomeActivityLocked(newUserId);
18255        } else {
18256            mStackSupervisor.resumeTopActivitiesLocked();
18257        }
18258        EventLogTags.writeAmSwitchUser(newUserId);
18259        getUserManagerLocked().userForeground(newUserId);
18260        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18261    }
18262
18263    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18264        completeSwitchAndInitalize(uss, newUserId, false, true);
18265    }
18266
18267    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18268            boolean clearInitializing, boolean clearSwitching) {
18269        boolean unfrozen = false;
18270        synchronized (this) {
18271            if (clearInitializing) {
18272                uss.initializing = false;
18273                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18274            }
18275            if (clearSwitching) {
18276                uss.switching = false;
18277            }
18278            if (!uss.switching && !uss.initializing) {
18279                mWindowManager.stopFreezingScreen();
18280                unfrozen = true;
18281            }
18282        }
18283        if (unfrozen) {
18284            final int N = mUserSwitchObservers.beginBroadcast();
18285            for (int i=0; i<N; i++) {
18286                try {
18287                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18288                } catch (RemoteException e) {
18289                }
18290            }
18291            mUserSwitchObservers.finishBroadcast();
18292        }
18293    }
18294
18295    void scheduleStartProfilesLocked() {
18296        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18297            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18298                    DateUtils.SECOND_IN_MILLIS);
18299        }
18300    }
18301
18302    void startProfilesLocked() {
18303        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18304        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18305                mCurrentUserId, false /* enabledOnly */);
18306        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18307        for (UserInfo user : profiles) {
18308            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18309                    && user.id != mCurrentUserId) {
18310                toStart.add(user);
18311            }
18312        }
18313        final int n = toStart.size();
18314        int i = 0;
18315        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18316            startUserInBackground(toStart.get(i).id);
18317        }
18318        if (i < n) {
18319            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18320        }
18321    }
18322
18323    void finishUserBoot(UserStartedState uss) {
18324        synchronized (this) {
18325            if (uss.mState == UserStartedState.STATE_BOOTING
18326                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18327                uss.mState = UserStartedState.STATE_RUNNING;
18328                final int userId = uss.mHandle.getIdentifier();
18329                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18330                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18331                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18332                broadcastIntentLocked(null, null, intent,
18333                        null, null, 0, null, null,
18334                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18335                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18336            }
18337        }
18338    }
18339
18340    void finishUserSwitch(UserStartedState uss) {
18341        synchronized (this) {
18342            finishUserBoot(uss);
18343
18344            startProfilesLocked();
18345
18346            int num = mUserLru.size();
18347            int i = 0;
18348            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18349                Integer oldUserId = mUserLru.get(i);
18350                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18351                if (oldUss == null) {
18352                    // Shouldn't happen, but be sane if it does.
18353                    mUserLru.remove(i);
18354                    num--;
18355                    continue;
18356                }
18357                if (oldUss.mState == UserStartedState.STATE_STOPPING
18358                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18359                    // This user is already stopping, doesn't count.
18360                    num--;
18361                    i++;
18362                    continue;
18363                }
18364                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18365                    // Owner and current can't be stopped, but count as running.
18366                    i++;
18367                    continue;
18368                }
18369                // This is a user to be stopped.
18370                stopUserLocked(oldUserId, null);
18371                num--;
18372                i++;
18373            }
18374        }
18375    }
18376
18377    @Override
18378    public int stopUser(final int userId, final IStopUserCallback callback) {
18379        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18380                != PackageManager.PERMISSION_GRANTED) {
18381            String msg = "Permission Denial: switchUser() from pid="
18382                    + Binder.getCallingPid()
18383                    + ", uid=" + Binder.getCallingUid()
18384                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18385            Slog.w(TAG, msg);
18386            throw new SecurityException(msg);
18387        }
18388        if (userId <= 0) {
18389            throw new IllegalArgumentException("Can't stop primary user " + userId);
18390        }
18391        synchronized (this) {
18392            return stopUserLocked(userId, callback);
18393        }
18394    }
18395
18396    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18397        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18398        if (mCurrentUserId == userId) {
18399            return ActivityManager.USER_OP_IS_CURRENT;
18400        }
18401
18402        final UserStartedState uss = mStartedUsers.get(userId);
18403        if (uss == null) {
18404            // User is not started, nothing to do...  but we do need to
18405            // callback if requested.
18406            if (callback != null) {
18407                mHandler.post(new Runnable() {
18408                    @Override
18409                    public void run() {
18410                        try {
18411                            callback.userStopped(userId);
18412                        } catch (RemoteException e) {
18413                        }
18414                    }
18415                });
18416            }
18417            return ActivityManager.USER_OP_SUCCESS;
18418        }
18419
18420        if (callback != null) {
18421            uss.mStopCallbacks.add(callback);
18422        }
18423
18424        if (uss.mState != UserStartedState.STATE_STOPPING
18425                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18426            uss.mState = UserStartedState.STATE_STOPPING;
18427            updateStartedUserArrayLocked();
18428
18429            long ident = Binder.clearCallingIdentity();
18430            try {
18431                // We are going to broadcast ACTION_USER_STOPPING and then
18432                // once that is done send a final ACTION_SHUTDOWN and then
18433                // stop the user.
18434                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18435                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18436                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18437                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18438                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18439                // This is the result receiver for the final shutdown broadcast.
18440                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18441                    @Override
18442                    public void performReceive(Intent intent, int resultCode, String data,
18443                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18444                        finishUserStop(uss);
18445                    }
18446                };
18447                // This is the result receiver for the initial stopping broadcast.
18448                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18449                    @Override
18450                    public void performReceive(Intent intent, int resultCode, String data,
18451                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18452                        // On to the next.
18453                        synchronized (ActivityManagerService.this) {
18454                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18455                                // Whoops, we are being started back up.  Abort, abort!
18456                                return;
18457                            }
18458                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18459                        }
18460                        mBatteryStatsService.noteEvent(
18461                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18462                                Integer.toString(userId), userId);
18463                        mSystemServiceManager.stopUser(userId);
18464                        broadcastIntentLocked(null, null, shutdownIntent,
18465                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18466                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18467                    }
18468                };
18469                // Kick things off.
18470                broadcastIntentLocked(null, null, stoppingIntent,
18471                        null, stoppingReceiver, 0, null, null,
18472                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18473                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18474            } finally {
18475                Binder.restoreCallingIdentity(ident);
18476            }
18477        }
18478
18479        return ActivityManager.USER_OP_SUCCESS;
18480    }
18481
18482    void finishUserStop(UserStartedState uss) {
18483        final int userId = uss.mHandle.getIdentifier();
18484        boolean stopped;
18485        ArrayList<IStopUserCallback> callbacks;
18486        synchronized (this) {
18487            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18488            if (mStartedUsers.get(userId) != uss) {
18489                stopped = false;
18490            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18491                stopped = false;
18492            } else {
18493                stopped = true;
18494                // User can no longer run.
18495                mStartedUsers.remove(userId);
18496                mUserLru.remove(Integer.valueOf(userId));
18497                updateStartedUserArrayLocked();
18498
18499                // Clean up all state and processes associated with the user.
18500                // Kill all the processes for the user.
18501                forceStopUserLocked(userId, "finish user");
18502            }
18503
18504            // Explicitly remove the old information in mRecentTasks.
18505            removeRecentTasksForUserLocked(userId);
18506        }
18507
18508        for (int i=0; i<callbacks.size(); i++) {
18509            try {
18510                if (stopped) callbacks.get(i).userStopped(userId);
18511                else callbacks.get(i).userStopAborted(userId);
18512            } catch (RemoteException e) {
18513            }
18514        }
18515
18516        if (stopped) {
18517            mSystemServiceManager.cleanupUser(userId);
18518            synchronized (this) {
18519                mStackSupervisor.removeUserLocked(userId);
18520            }
18521        }
18522    }
18523
18524    @Override
18525    public UserInfo getCurrentUser() {
18526        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18527                != PackageManager.PERMISSION_GRANTED) && (
18528                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18529                != PackageManager.PERMISSION_GRANTED)) {
18530            String msg = "Permission Denial: getCurrentUser() from pid="
18531                    + Binder.getCallingPid()
18532                    + ", uid=" + Binder.getCallingUid()
18533                    + " requires " + INTERACT_ACROSS_USERS;
18534            Slog.w(TAG, msg);
18535            throw new SecurityException(msg);
18536        }
18537        synchronized (this) {
18538            return getUserManagerLocked().getUserInfo(mCurrentUserId);
18539        }
18540    }
18541
18542    int getCurrentUserIdLocked() {
18543        return mCurrentUserId;
18544    }
18545
18546    @Override
18547    public boolean isUserRunning(int userId, boolean orStopped) {
18548        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18549                != PackageManager.PERMISSION_GRANTED) {
18550            String msg = "Permission Denial: isUserRunning() from pid="
18551                    + Binder.getCallingPid()
18552                    + ", uid=" + Binder.getCallingUid()
18553                    + " requires " + INTERACT_ACROSS_USERS;
18554            Slog.w(TAG, msg);
18555            throw new SecurityException(msg);
18556        }
18557        synchronized (this) {
18558            return isUserRunningLocked(userId, orStopped);
18559        }
18560    }
18561
18562    boolean isUserRunningLocked(int userId, boolean orStopped) {
18563        UserStartedState state = mStartedUsers.get(userId);
18564        if (state == null) {
18565            return false;
18566        }
18567        if (orStopped) {
18568            return true;
18569        }
18570        return state.mState != UserStartedState.STATE_STOPPING
18571                && state.mState != UserStartedState.STATE_SHUTDOWN;
18572    }
18573
18574    @Override
18575    public int[] getRunningUserIds() {
18576        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18577                != PackageManager.PERMISSION_GRANTED) {
18578            String msg = "Permission Denial: isUserRunning() from pid="
18579                    + Binder.getCallingPid()
18580                    + ", uid=" + Binder.getCallingUid()
18581                    + " requires " + INTERACT_ACROSS_USERS;
18582            Slog.w(TAG, msg);
18583            throw new SecurityException(msg);
18584        }
18585        synchronized (this) {
18586            return mStartedUserArray;
18587        }
18588    }
18589
18590    private void updateStartedUserArrayLocked() {
18591        int num = 0;
18592        for (int i=0; i<mStartedUsers.size();  i++) {
18593            UserStartedState uss = mStartedUsers.valueAt(i);
18594            // This list does not include stopping users.
18595            if (uss.mState != UserStartedState.STATE_STOPPING
18596                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18597                num++;
18598            }
18599        }
18600        mStartedUserArray = new int[num];
18601        num = 0;
18602        for (int i=0; i<mStartedUsers.size();  i++) {
18603            UserStartedState uss = mStartedUsers.valueAt(i);
18604            if (uss.mState != UserStartedState.STATE_STOPPING
18605                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18606                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18607                num++;
18608            }
18609        }
18610    }
18611
18612    @Override
18613    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18614        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18615                != PackageManager.PERMISSION_GRANTED) {
18616            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18617                    + Binder.getCallingPid()
18618                    + ", uid=" + Binder.getCallingUid()
18619                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18620            Slog.w(TAG, msg);
18621            throw new SecurityException(msg);
18622        }
18623
18624        mUserSwitchObservers.register(observer);
18625    }
18626
18627    @Override
18628    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18629        mUserSwitchObservers.unregister(observer);
18630    }
18631
18632    private boolean userExists(int userId) {
18633        if (userId == 0) {
18634            return true;
18635        }
18636        UserManagerService ums = getUserManagerLocked();
18637        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18638    }
18639
18640    int[] getUsersLocked() {
18641        UserManagerService ums = getUserManagerLocked();
18642        return ums != null ? ums.getUserIds() : new int[] { 0 };
18643    }
18644
18645    UserManagerService getUserManagerLocked() {
18646        if (mUserManager == null) {
18647            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18648            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18649        }
18650        return mUserManager;
18651    }
18652
18653    private int applyUserId(int uid, int userId) {
18654        return UserHandle.getUid(userId, uid);
18655    }
18656
18657    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18658        if (info == null) return null;
18659        ApplicationInfo newInfo = new ApplicationInfo(info);
18660        newInfo.uid = applyUserId(info.uid, userId);
18661        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18662                + info.packageName;
18663        return newInfo;
18664    }
18665
18666    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18667        if (aInfo == null
18668                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18669            return aInfo;
18670        }
18671
18672        ActivityInfo info = new ActivityInfo(aInfo);
18673        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18674        return info;
18675    }
18676
18677    private final class LocalService extends ActivityManagerInternal {
18678        @Override
18679        public void goingToSleep() {
18680            ActivityManagerService.this.goingToSleep();
18681        }
18682
18683        @Override
18684        public void wakingUp() {
18685            ActivityManagerService.this.wakingUp();
18686        }
18687
18688        @Override
18689        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18690                String processName, String abiOverride, int uid, Runnable crashHandler) {
18691            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18692                    processName, abiOverride, uid, crashHandler);
18693        }
18694    }
18695
18696    /**
18697     * An implementation of IAppTask, that allows an app to manage its own tasks via
18698     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18699     * only the process that calls getAppTasks() can call the AppTask methods.
18700     */
18701    class AppTaskImpl extends IAppTask.Stub {
18702        private int mTaskId;
18703        private int mCallingUid;
18704
18705        public AppTaskImpl(int taskId, int callingUid) {
18706            mTaskId = taskId;
18707            mCallingUid = callingUid;
18708        }
18709
18710        private void checkCaller() {
18711            if (mCallingUid != Binder.getCallingUid()) {
18712                throw new SecurityException("Caller " + mCallingUid
18713                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18714            }
18715        }
18716
18717        @Override
18718        public void finishAndRemoveTask() {
18719            checkCaller();
18720
18721            synchronized (ActivityManagerService.this) {
18722                long origId = Binder.clearCallingIdentity();
18723                try {
18724                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18725                    if (tr == null) {
18726                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18727                    }
18728                    // Only kill the process if we are not a new document
18729                    int flags = tr.getBaseIntent().getFlags();
18730                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18731                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18732                    removeTaskByIdLocked(mTaskId,
18733                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18734                } finally {
18735                    Binder.restoreCallingIdentity(origId);
18736                }
18737            }
18738        }
18739
18740        @Override
18741        public ActivityManager.RecentTaskInfo getTaskInfo() {
18742            checkCaller();
18743
18744            synchronized (ActivityManagerService.this) {
18745                long origId = Binder.clearCallingIdentity();
18746                try {
18747                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18748                    if (tr == null) {
18749                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18750                    }
18751                    return createRecentTaskInfoFromTaskRecord(tr);
18752                } finally {
18753                    Binder.restoreCallingIdentity(origId);
18754                }
18755            }
18756        }
18757
18758        @Override
18759        public void moveToFront() {
18760            checkCaller();
18761
18762            final TaskRecord tr;
18763            synchronized (ActivityManagerService.this) {
18764                tr = recentTaskForIdLocked(mTaskId);
18765                if (tr == null) {
18766                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18767                }
18768                if (tr.getRootActivity() != null) {
18769                    long origId = Binder.clearCallingIdentity();
18770                    try {
18771                        moveTaskToFrontLocked(tr.taskId, 0, null);
18772                        return;
18773                    } finally {
18774                        Binder.restoreCallingIdentity(origId);
18775                    }
18776                }
18777            }
18778
18779            startActivityFromRecentsInner(tr.taskId, null);
18780        }
18781
18782        @Override
18783        public int startActivity(IBinder whoThread, String callingPackage,
18784                Intent intent, String resolvedType, Bundle options) {
18785            checkCaller();
18786
18787            int callingUser = UserHandle.getCallingUserId();
18788            TaskRecord tr;
18789            IApplicationThread appThread;
18790            synchronized (ActivityManagerService.this) {
18791                tr = recentTaskForIdLocked(mTaskId);
18792                if (tr == null) {
18793                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18794                }
18795                appThread = ApplicationThreadNative.asInterface(whoThread);
18796                if (appThread == null) {
18797                    throw new IllegalArgumentException("Bad app thread " + appThread);
18798                }
18799            }
18800            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18801                    resolvedType, null, null, null, null, 0, 0, null, null,
18802                    null, options, callingUser, null, tr);
18803        }
18804
18805        @Override
18806        public void setExcludeFromRecents(boolean exclude) {
18807            checkCaller();
18808
18809            synchronized (ActivityManagerService.this) {
18810                long origId = Binder.clearCallingIdentity();
18811                try {
18812                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18813                    if (tr == null) {
18814                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18815                    }
18816                    Intent intent = tr.getBaseIntent();
18817                    if (exclude) {
18818                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18819                    } else {
18820                        intent.setFlags(intent.getFlags()
18821                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18822                    }
18823                } finally {
18824                    Binder.restoreCallingIdentity(origId);
18825                }
18826            }
18827        }
18828    }
18829}
18830