ActivityManagerService.java revision f71edcaa1446c54956ea5d29a44343361a668755
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        ProcessRecord app;
2902        if (!isolated) {
2903            app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
2904        } else {
2905            // If this is an isolated process, it can't re-use an existing process.
2906            app = null;
2907        }
2908        // We don't have to do anything more if:
2909        // (1) There is an existing application record; and
2910        // (2) The caller doesn't think it is dead, OR there is no thread
2911        //     object attached to it so we know it couldn't have crashed; and
2912        // (3) There is a pid assigned to it, so it is either starting or
2913        //     already running.
2914        if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
2915                + " app=" + app + " knownToBeDead=" + knownToBeDead
2916                + " thread=" + (app != null ? app.thread : null)
2917                + " pid=" + (app != null ? app.pid : -1));
2918        if (app != null && app.pid > 0) {
2919            if (!knownToBeDead || app.thread == null) {
2920                // We already have the app running, or are waiting for it to
2921                // come up (we have a pid but not yet its thread), so keep it.
2922                if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
2923                // If this is a new package in the process, add the package to the list
2924                app.addPackage(info.packageName, info.versionCode, mProcessStats);
2925                return app;
2926            }
2927
2928            // An application record is attached to a previous process,
2929            // clean it up now.
2930            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
2931            Process.killProcessGroup(app.info.uid, app.pid);
2932            handleAppDiedLocked(app, true, true);
2933        }
2934
2935        String hostingNameStr = hostingName != null
2936                ? hostingName.flattenToShortString() : null;
2937
2938        if (!isolated) {
2939            if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2940                // If we are in the background, then check to see if this process
2941                // is bad.  If so, we will just silently fail.
2942                if (mBadProcesses.get(info.processName, info.uid) != null) {
2943                    if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2944                            + "/" + info.processName);
2945                    return null;
2946                }
2947            } else {
2948                // When the user is explicitly starting a process, then clear its
2949                // crash count so that we won't make it bad until they see at
2950                // least one crash dialog again, and make the process good again
2951                // if it had been bad.
2952                if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
2953                        + "/" + info.processName);
2954                mProcessCrashTimes.remove(info.processName, info.uid);
2955                if (mBadProcesses.get(info.processName, info.uid) != null) {
2956                    EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2957                            UserHandle.getUserId(info.uid), info.uid,
2958                            info.processName);
2959                    mBadProcesses.remove(info.processName, info.uid);
2960                    if (app != null) {
2961                        app.bad = false;
2962                    }
2963                }
2964            }
2965        }
2966
2967        if (app == null) {
2968            app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
2969            app.crashHandler = crashHandler;
2970            if (app == null) {
2971                Slog.w(TAG, "Failed making new process record for "
2972                        + processName + "/" + info.uid + " isolated=" + isolated);
2973                return null;
2974            }
2975            mProcessNames.put(processName, app.uid, app);
2976            if (isolated) {
2977                mIsolatedProcesses.put(app.uid, app);
2978            }
2979        } else {
2980            // If this is a new package in the process, add the package to the list
2981            app.addPackage(info.packageName, info.versionCode, mProcessStats);
2982        }
2983
2984        // If the system is not ready yet, then hold off on starting this
2985        // process until it is.
2986        if (!mProcessesReady
2987                && !isAllowedWhileBooting(info)
2988                && !allowWhileBooting) {
2989            if (!mProcessesOnHold.contains(app)) {
2990                mProcessesOnHold.add(app);
2991            }
2992            if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
2993            return app;
2994        }
2995
2996        startProcessLocked(
2997                app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
2998        return (app.pid != 0) ? app : null;
2999    }
3000
3001    boolean isAllowedWhileBooting(ApplicationInfo ai) {
3002        return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3003    }
3004
3005    private final void startProcessLocked(ProcessRecord app,
3006            String hostingType, String hostingNameStr) {
3007        startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3008                null /* entryPoint */, null /* entryPointArgs */);
3009    }
3010
3011    private final void startProcessLocked(ProcessRecord app, String hostingType,
3012            String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3013        if (app.pid > 0 && app.pid != MY_PID) {
3014            synchronized (mPidsSelfLocked) {
3015                mPidsSelfLocked.remove(app.pid);
3016                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3017            }
3018            app.setPid(0);
3019        }
3020
3021        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3022                "startProcessLocked removing on hold: " + app);
3023        mProcessesOnHold.remove(app);
3024
3025        updateCpuStats();
3026
3027        try {
3028            int uid = app.uid;
3029
3030            int[] gids = null;
3031            int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3032            if (!app.isolated) {
3033                int[] permGids = null;
3034                try {
3035                    final PackageManager pm = mContext.getPackageManager();
3036                    permGids = pm.getPackageGids(app.info.packageName);
3037
3038                    if (Environment.isExternalStorageEmulated()) {
3039                        if (pm.checkPermission(
3040                                android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
3041                                app.info.packageName) == PERMISSION_GRANTED) {
3042                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
3043                        } else {
3044                            mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
3045                        }
3046                    }
3047                } catch (PackageManager.NameNotFoundException e) {
3048                    Slog.w(TAG, "Unable to retrieve gids", e);
3049                }
3050
3051                /*
3052                 * Add shared application and profile GIDs so applications can share some
3053                 * resources like shared libraries and access user-wide resources
3054                 */
3055                if (permGids == null) {
3056                    gids = new int[2];
3057                } else {
3058                    gids = new int[permGids.length + 2];
3059                    System.arraycopy(permGids, 0, gids, 2, permGids.length);
3060                }
3061                gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3062                gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3063            }
3064            if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3065                if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3066                        && mTopComponent != null
3067                        && app.processName.equals(mTopComponent.getPackageName())) {
3068                    uid = 0;
3069                }
3070                if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3071                        && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3072                    uid = 0;
3073                }
3074            }
3075            int debugFlags = 0;
3076            if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3077                debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3078                // Also turn on CheckJNI for debuggable apps. It's quite
3079                // awkward to turn on otherwise.
3080                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3081            }
3082            // Run the app in safe mode if its manifest requests so or the
3083            // system is booted in safe mode.
3084            if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3085                mSafeMode == true) {
3086                debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3087            }
3088            if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3089                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3090            }
3091            if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3092                debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3093            }
3094            if ("1".equals(SystemProperties.get("debug.assert"))) {
3095                debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3096            }
3097
3098            String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3099            if (requiredAbi == null) {
3100                requiredAbi = Build.SUPPORTED_ABIS[0];
3101            }
3102
3103            // Start the process.  It will either succeed and return a result containing
3104            // the PID of the new process, or else throw a RuntimeException.
3105            boolean isActivityProcess = (entryPoint == null);
3106            if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3107            Process.ProcessStartResult startResult = Process.start(entryPoint,
3108                    app.processName, uid, uid, gids, debugFlags, mountExternal,
3109                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
3110
3111            if (app.isolated) {
3112                mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3113            }
3114            mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3115
3116            EventLog.writeEvent(EventLogTags.AM_PROC_START,
3117                    UserHandle.getUserId(uid), startResult.pid, uid,
3118                    app.processName, hostingType,
3119                    hostingNameStr != null ? hostingNameStr : "");
3120
3121            if (app.persistent) {
3122                Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3123            }
3124
3125            StringBuilder buf = mStringBuilder;
3126            buf.setLength(0);
3127            buf.append("Start proc ");
3128            buf.append(app.processName);
3129            if (!isActivityProcess) {
3130                buf.append(" [");
3131                buf.append(entryPoint);
3132                buf.append("]");
3133            }
3134            buf.append(" for ");
3135            buf.append(hostingType);
3136            if (hostingNameStr != null) {
3137                buf.append(" ");
3138                buf.append(hostingNameStr);
3139            }
3140            buf.append(": pid=");
3141            buf.append(startResult.pid);
3142            buf.append(" uid=");
3143            buf.append(uid);
3144            buf.append(" gids={");
3145            if (gids != null) {
3146                for (int gi=0; gi<gids.length; gi++) {
3147                    if (gi != 0) buf.append(", ");
3148                    buf.append(gids[gi]);
3149
3150                }
3151            }
3152            buf.append("}");
3153            if (requiredAbi != null) {
3154                buf.append(" abi=");
3155                buf.append(requiredAbi);
3156            }
3157            Slog.i(TAG, buf.toString());
3158            app.setPid(startResult.pid);
3159            app.usingWrapper = startResult.usingWrapper;
3160            app.removed = false;
3161            app.killedByAm = false;
3162            synchronized (mPidsSelfLocked) {
3163                this.mPidsSelfLocked.put(startResult.pid, app);
3164                if (isActivityProcess) {
3165                    Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3166                    msg.obj = app;
3167                    mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3168                            ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3169                }
3170            }
3171        } catch (RuntimeException e) {
3172            // XXX do better error recovery.
3173            app.setPid(0);
3174            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3175            if (app.isolated) {
3176                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3177            }
3178            Slog.e(TAG, "Failure starting process " + app.processName, e);
3179        }
3180    }
3181
3182    void updateUsageStats(ActivityRecord component, boolean resumed) {
3183        if (DEBUG_SWITCH) Slog.d(TAG, "updateUsageStats: comp=" + component + "res=" + resumed);
3184        final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3185        if (resumed) {
3186            if (mUsageStatsService != null) {
3187                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3188                        System.currentTimeMillis(),
3189                        UsageEvents.Event.MOVE_TO_FOREGROUND);
3190            }
3191            synchronized (stats) {
3192                stats.noteActivityResumedLocked(component.app.uid);
3193            }
3194        } else {
3195            if (mUsageStatsService != null) {
3196                mUsageStatsService.reportEvent(component.realActivity, component.userId,
3197                        System.currentTimeMillis(),
3198                        UsageEvents.Event.MOVE_TO_BACKGROUND);
3199            }
3200            synchronized (stats) {
3201                stats.noteActivityPausedLocked(component.app.uid);
3202            }
3203        }
3204    }
3205
3206    Intent getHomeIntent() {
3207        Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3208        intent.setComponent(mTopComponent);
3209        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3210            intent.addCategory(Intent.CATEGORY_HOME);
3211        }
3212        return intent;
3213    }
3214
3215    boolean startHomeActivityLocked(int userId) {
3216        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3217                && mTopAction == null) {
3218            // We are running in factory test mode, but unable to find
3219            // the factory test app, so just sit around displaying the
3220            // error message and don't try to start anything.
3221            return false;
3222        }
3223        Intent intent = getHomeIntent();
3224        ActivityInfo aInfo =
3225            resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3226        if (aInfo != null) {
3227            intent.setComponent(new ComponentName(
3228                    aInfo.applicationInfo.packageName, aInfo.name));
3229            // Don't do this if the home app is currently being
3230            // instrumented.
3231            aInfo = new ActivityInfo(aInfo);
3232            aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3233            ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3234                    aInfo.applicationInfo.uid, true);
3235            if (app == null || app.instrumentationClass == null) {
3236                intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3237                mStackSupervisor.startHomeActivity(intent, aInfo);
3238            }
3239        }
3240
3241        return true;
3242    }
3243
3244    private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3245        ActivityInfo ai = null;
3246        ComponentName comp = intent.getComponent();
3247        try {
3248            if (comp != null) {
3249                ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3250            } else {
3251                ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3252                        intent,
3253                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3254                            flags, userId);
3255
3256                if (info != null) {
3257                    ai = info.activityInfo;
3258                }
3259            }
3260        } catch (RemoteException e) {
3261            // ignore
3262        }
3263
3264        return ai;
3265    }
3266
3267    /**
3268     * Starts the "new version setup screen" if appropriate.
3269     */
3270    void startSetupActivityLocked() {
3271        // Only do this once per boot.
3272        if (mCheckedForSetup) {
3273            return;
3274        }
3275
3276        // We will show this screen if the current one is a different
3277        // version than the last one shown, and we are not running in
3278        // low-level factory test mode.
3279        final ContentResolver resolver = mContext.getContentResolver();
3280        if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3281                Settings.Global.getInt(resolver,
3282                        Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3283            mCheckedForSetup = true;
3284
3285            // See if we should be showing the platform update setup UI.
3286            Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3287            List<ResolveInfo> ris = mContext.getPackageManager()
3288                    .queryIntentActivities(intent, PackageManager.GET_META_DATA);
3289
3290            // We don't allow third party apps to replace this.
3291            ResolveInfo ri = null;
3292            for (int i=0; ris != null && i<ris.size(); i++) {
3293                if ((ris.get(i).activityInfo.applicationInfo.flags
3294                        & ApplicationInfo.FLAG_SYSTEM) != 0) {
3295                    ri = ris.get(i);
3296                    break;
3297                }
3298            }
3299
3300            if (ri != null) {
3301                String vers = ri.activityInfo.metaData != null
3302                        ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3303                        : null;
3304                if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3305                    vers = ri.activityInfo.applicationInfo.metaData.getString(
3306                            Intent.METADATA_SETUP_VERSION);
3307                }
3308                String lastVers = Settings.Secure.getString(
3309                        resolver, Settings.Secure.LAST_SETUP_SHOWN);
3310                if (vers != null && !vers.equals(lastVers)) {
3311                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3312                    intent.setComponent(new ComponentName(
3313                            ri.activityInfo.packageName, ri.activityInfo.name));
3314                    mStackSupervisor.startActivityLocked(null, intent, null, ri.activityInfo,
3315                            null, null, null, null, 0, 0, 0, null, 0, null, false, null, null,
3316                            null);
3317                }
3318            }
3319        }
3320    }
3321
3322    CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3323        return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3324    }
3325
3326    void enforceNotIsolatedCaller(String caller) {
3327        if (UserHandle.isIsolated(Binder.getCallingUid())) {
3328            throw new SecurityException("Isolated process not allowed to call " + caller);
3329        }
3330    }
3331
3332    @Override
3333    public int getFrontActivityScreenCompatMode() {
3334        enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3335        synchronized (this) {
3336            return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3337        }
3338    }
3339
3340    @Override
3341    public void setFrontActivityScreenCompatMode(int mode) {
3342        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3343                "setFrontActivityScreenCompatMode");
3344        synchronized (this) {
3345            mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3346        }
3347    }
3348
3349    @Override
3350    public int getPackageScreenCompatMode(String packageName) {
3351        enforceNotIsolatedCaller("getPackageScreenCompatMode");
3352        synchronized (this) {
3353            return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3354        }
3355    }
3356
3357    @Override
3358    public void setPackageScreenCompatMode(String packageName, int mode) {
3359        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3360                "setPackageScreenCompatMode");
3361        synchronized (this) {
3362            mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3363        }
3364    }
3365
3366    @Override
3367    public boolean getPackageAskScreenCompat(String packageName) {
3368        enforceNotIsolatedCaller("getPackageAskScreenCompat");
3369        synchronized (this) {
3370            return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3371        }
3372    }
3373
3374    @Override
3375    public void setPackageAskScreenCompat(String packageName, boolean ask) {
3376        enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3377                "setPackageAskScreenCompat");
3378        synchronized (this) {
3379            mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3380        }
3381    }
3382
3383    private void dispatchProcessesChanged() {
3384        int N;
3385        synchronized (this) {
3386            N = mPendingProcessChanges.size();
3387            if (mActiveProcessChanges.length < N) {
3388                mActiveProcessChanges = new ProcessChangeItem[N];
3389            }
3390            mPendingProcessChanges.toArray(mActiveProcessChanges);
3391            mAvailProcessChanges.addAll(mPendingProcessChanges);
3392            mPendingProcessChanges.clear();
3393            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
3394        }
3395
3396        int i = mProcessObservers.beginBroadcast();
3397        while (i > 0) {
3398            i--;
3399            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3400            if (observer != null) {
3401                try {
3402                    for (int j=0; j<N; j++) {
3403                        ProcessChangeItem item = mActiveProcessChanges[j];
3404                        if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3405                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
3406                                    + item.pid + " uid=" + item.uid + ": "
3407                                    + item.foregroundActivities);
3408                            observer.onForegroundActivitiesChanged(item.pid, item.uid,
3409                                    item.foregroundActivities);
3410                        }
3411                        if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3412                            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "PROCSTATE CHANGED pid="
3413                                    + item.pid + " uid=" + item.uid + ": " + item.processState);
3414                            observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3415                        }
3416                    }
3417                } catch (RemoteException e) {
3418                }
3419            }
3420        }
3421        mProcessObservers.finishBroadcast();
3422    }
3423
3424    private void dispatchProcessDied(int pid, int uid) {
3425        int i = mProcessObservers.beginBroadcast();
3426        while (i > 0) {
3427            i--;
3428            final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3429            if (observer != null) {
3430                try {
3431                    observer.onProcessDied(pid, uid);
3432                } catch (RemoteException e) {
3433                }
3434            }
3435        }
3436        mProcessObservers.finishBroadcast();
3437    }
3438
3439    @Override
3440    public final int startActivity(IApplicationThread caller, String callingPackage,
3441            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3442            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3443        return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
3444            resultWho, requestCode, startFlags, profilerInfo, options,
3445            UserHandle.getCallingUserId());
3446    }
3447
3448    @Override
3449    public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
3450            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3451            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3452        enforceNotIsolatedCaller("startActivity");
3453        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3454                false, ALLOW_FULL_ONLY, "startActivity", null);
3455        // TODO: Switch to user app stacks here.
3456        return mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3457                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3458                profilerInfo, null, null, options, userId, null, null);
3459    }
3460
3461    @Override
3462    public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
3463            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3464            int startFlags, ProfilerInfo profilerInfo, Bundle options) {
3465
3466        // This is very dangerous -- it allows you to perform a start activity (including
3467        // permission grants) as any app that may launch one of your own activities.  So
3468        // we will only allow this to be done from activities that are part of the core framework,
3469        // and then only when they are running as the system.
3470        final ActivityRecord sourceRecord;
3471        final int targetUid;
3472        final String targetPackage;
3473        synchronized (this) {
3474            if (resultTo == null) {
3475                throw new SecurityException("Must be called from an activity");
3476            }
3477            sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
3478            if (sourceRecord == null) {
3479                throw new SecurityException("Called with bad activity token: " + resultTo);
3480            }
3481            if (!sourceRecord.info.packageName.equals("android")) {
3482                throw new SecurityException(
3483                        "Must be called from an activity that is declared in the android package");
3484            }
3485            if (sourceRecord.app == null) {
3486                throw new SecurityException("Called without a process attached to activity");
3487            }
3488            if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
3489                // This is still okay, as long as this activity is running under the
3490                // uid of the original calling activity.
3491                if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
3492                    throw new SecurityException(
3493                            "Calling activity in uid " + sourceRecord.app.uid
3494                                    + " must be system uid or original calling uid "
3495                                    + sourceRecord.launchedFromUid);
3496                }
3497            }
3498            targetUid = sourceRecord.launchedFromUid;
3499            targetPackage = sourceRecord.launchedFromPackage;
3500        }
3501
3502        // TODO: Switch to user app stacks here.
3503        try {
3504            int ret = mStackSupervisor.startActivityMayWait(null, targetUid, targetPackage, intent,
3505                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
3506                    null, null, options, UserHandle.getUserId(sourceRecord.app.uid), null, null);
3507            return ret;
3508        } catch (SecurityException e) {
3509            // XXX need to figure out how to propagate to original app.
3510            // A SecurityException here is generally actually a fault of the original
3511            // calling activity (such as a fairly granting permissions), so propagate it
3512            // back to them.
3513            /*
3514            StringBuilder msg = new StringBuilder();
3515            msg.append("While launching");
3516            msg.append(intent.toString());
3517            msg.append(": ");
3518            msg.append(e.getMessage());
3519            */
3520            throw e;
3521        }
3522    }
3523
3524    @Override
3525    public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
3526            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3527            int startFlags, ProfilerInfo profilerInfo, Bundle options, int userId) {
3528        enforceNotIsolatedCaller("startActivityAndWait");
3529        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3530                false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
3531        WaitResult res = new WaitResult();
3532        // TODO: Switch to user app stacks here.
3533        mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
3534                null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
3535                options, userId, null, null);
3536        return res;
3537    }
3538
3539    @Override
3540    public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
3541            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
3542            int startFlags, Configuration config, Bundle options, int userId) {
3543        enforceNotIsolatedCaller("startActivityWithConfig");
3544        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3545                false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
3546        // TODO: Switch to user app stacks here.
3547        int ret = mStackSupervisor.startActivityMayWait(caller, -1, callingPackage, intent,
3548                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3549                null, null, config, options, userId, null, null);
3550        return ret;
3551    }
3552
3553    @Override
3554    public int startActivityIntentSender(IApplicationThread caller,
3555            IntentSender intent, Intent fillInIntent, String resolvedType,
3556            IBinder resultTo, String resultWho, int requestCode,
3557            int flagsMask, int flagsValues, Bundle options) {
3558        enforceNotIsolatedCaller("startActivityIntentSender");
3559        // Refuse possible leaked file descriptors
3560        if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
3561            throw new IllegalArgumentException("File descriptors passed in Intent");
3562        }
3563
3564        IIntentSender sender = intent.getTarget();
3565        if (!(sender instanceof PendingIntentRecord)) {
3566            throw new IllegalArgumentException("Bad PendingIntent object");
3567        }
3568
3569        PendingIntentRecord pir = (PendingIntentRecord)sender;
3570
3571        synchronized (this) {
3572            // If this is coming from the currently resumed activity, it is
3573            // effectively saying that app switches are allowed at this point.
3574            final ActivityStack stack = getFocusedStack();
3575            if (stack.mResumedActivity != null &&
3576                    stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
3577                mAppSwitchesAllowedTime = 0;
3578            }
3579        }
3580        int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
3581                resultTo, resultWho, requestCode, flagsMask, flagsValues, options, null);
3582        return ret;
3583    }
3584
3585    @Override
3586    public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
3587            Intent intent, String resolvedType, IVoiceInteractionSession session,
3588            IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
3589            Bundle options, int userId) {
3590        if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
3591                != PackageManager.PERMISSION_GRANTED) {
3592            String msg = "Permission Denial: startVoiceActivity() from pid="
3593                    + Binder.getCallingPid()
3594                    + ", uid=" + Binder.getCallingUid()
3595                    + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
3596            Slog.w(TAG, msg);
3597            throw new SecurityException(msg);
3598        }
3599        if (session == null || interactor == null) {
3600            throw new NullPointerException("null session or interactor");
3601        }
3602        userId = handleIncomingUser(callingPid, callingUid, userId,
3603                false, ALLOW_FULL_ONLY, "startVoiceActivity", null);
3604        // TODO: Switch to user app stacks here.
3605        return mStackSupervisor.startActivityMayWait(null, callingUid, callingPackage, intent,
3606                resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
3607                null, options, userId, null, null);
3608    }
3609
3610    @Override
3611    public boolean startNextMatchingActivity(IBinder callingActivity,
3612            Intent intent, Bundle options) {
3613        // Refuse possible leaked file descriptors
3614        if (intent != null && intent.hasFileDescriptors() == true) {
3615            throw new IllegalArgumentException("File descriptors passed in Intent");
3616        }
3617
3618        synchronized (this) {
3619            final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
3620            if (r == null) {
3621                ActivityOptions.abort(options);
3622                return false;
3623            }
3624            if (r.app == null || r.app.thread == null) {
3625                // The caller is not running...  d'oh!
3626                ActivityOptions.abort(options);
3627                return false;
3628            }
3629            intent = new Intent(intent);
3630            // The caller is not allowed to change the data.
3631            intent.setDataAndType(r.intent.getData(), r.intent.getType());
3632            // And we are resetting to find the next component...
3633            intent.setComponent(null);
3634
3635            final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
3636
3637            ActivityInfo aInfo = null;
3638            try {
3639                List<ResolveInfo> resolves =
3640                    AppGlobals.getPackageManager().queryIntentActivities(
3641                            intent, r.resolvedType,
3642                            PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
3643                            UserHandle.getCallingUserId());
3644
3645                // Look for the original activity in the list...
3646                final int N = resolves != null ? resolves.size() : 0;
3647                for (int i=0; i<N; i++) {
3648                    ResolveInfo rInfo = resolves.get(i);
3649                    if (rInfo.activityInfo.packageName.equals(r.packageName)
3650                            && rInfo.activityInfo.name.equals(r.info.name)) {
3651                        // We found the current one...  the next matching is
3652                        // after it.
3653                        i++;
3654                        if (i<N) {
3655                            aInfo = resolves.get(i).activityInfo;
3656                        }
3657                        if (debug) {
3658                            Slog.v(TAG, "Next matching activity: found current " + r.packageName
3659                                    + "/" + r.info.name);
3660                            Slog.v(TAG, "Next matching activity: next is " + aInfo.packageName
3661                                    + "/" + aInfo.name);
3662                        }
3663                        break;
3664                    }
3665                }
3666            } catch (RemoteException e) {
3667            }
3668
3669            if (aInfo == null) {
3670                // Nobody who is next!
3671                ActivityOptions.abort(options);
3672                if (debug) Slog.d(TAG, "Next matching activity: nothing found");
3673                return false;
3674            }
3675
3676            intent.setComponent(new ComponentName(
3677                    aInfo.applicationInfo.packageName, aInfo.name));
3678            intent.setFlags(intent.getFlags()&~(
3679                    Intent.FLAG_ACTIVITY_FORWARD_RESULT|
3680                    Intent.FLAG_ACTIVITY_CLEAR_TOP|
3681                    Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
3682                    Intent.FLAG_ACTIVITY_NEW_TASK));
3683
3684            // Okay now we need to start the new activity, replacing the
3685            // currently running activity.  This is a little tricky because
3686            // we want to start the new one as if the current one is finished,
3687            // but not finish the current one first so that there is no flicker.
3688            // And thus...
3689            final boolean wasFinishing = r.finishing;
3690            r.finishing = true;
3691
3692            // Propagate reply information over to the new activity.
3693            final ActivityRecord resultTo = r.resultTo;
3694            final String resultWho = r.resultWho;
3695            final int requestCode = r.requestCode;
3696            r.resultTo = null;
3697            if (resultTo != null) {
3698                resultTo.removeResultsLocked(r, resultWho, requestCode);
3699            }
3700
3701            final long origId = Binder.clearCallingIdentity();
3702            int res = mStackSupervisor.startActivityLocked(r.app.thread, intent,
3703                    r.resolvedType, aInfo, null, null, resultTo != null ? resultTo.appToken : null,
3704                    resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
3705                    options, false, null, null, null);
3706            Binder.restoreCallingIdentity(origId);
3707
3708            r.finishing = wasFinishing;
3709            if (res != ActivityManager.START_SUCCESS) {
3710                return false;
3711            }
3712            return true;
3713        }
3714    }
3715
3716    @Override
3717    public final int startActivityFromRecents(int taskId, Bundle options) {
3718        if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
3719            String msg = "Permission Denial: startActivityFromRecents called without " +
3720                    START_TASKS_FROM_RECENTS;
3721            Slog.w(TAG, msg);
3722            throw new SecurityException(msg);
3723        }
3724        return startActivityFromRecentsInner(taskId, options);
3725    }
3726
3727    final int startActivityFromRecentsInner(int taskId, Bundle options) {
3728        final TaskRecord task;
3729        final int callingUid;
3730        final String callingPackage;
3731        final Intent intent;
3732        final int userId;
3733        synchronized (this) {
3734            task = recentTaskForIdLocked(taskId);
3735            if (task == null) {
3736                throw new IllegalArgumentException("Task " + taskId + " not found.");
3737            }
3738            callingUid = task.mCallingUid;
3739            callingPackage = task.mCallingPackage;
3740            intent = task.intent;
3741            intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
3742            userId = task.userId;
3743        }
3744        return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
3745                options, userId, null, task);
3746    }
3747
3748    final int startActivityInPackage(int uid, String callingPackage,
3749            Intent intent, String resolvedType, IBinder resultTo,
3750            String resultWho, int requestCode, int startFlags, Bundle options, int userId,
3751            IActivityContainer container, TaskRecord inTask) {
3752
3753        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3754                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3755
3756        // TODO: Switch to user app stacks here.
3757        int ret = mStackSupervisor.startActivityMayWait(null, uid, callingPackage, intent,
3758                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
3759                null, null, null, options, userId, container, inTask);
3760        return ret;
3761    }
3762
3763    @Override
3764    public final int startActivities(IApplicationThread caller, String callingPackage,
3765            Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
3766            int userId) {
3767        enforceNotIsolatedCaller("startActivities");
3768        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3769                false, ALLOW_FULL_ONLY, "startActivity", null);
3770        // TODO: Switch to user app stacks here.
3771        int ret = mStackSupervisor.startActivities(caller, -1, callingPackage, intents,
3772                resolvedTypes, resultTo, options, userId);
3773        return ret;
3774    }
3775
3776    final int startActivitiesInPackage(int uid, String callingPackage,
3777            Intent[] intents, String[] resolvedTypes, IBinder resultTo,
3778            Bundle options, int userId) {
3779
3780        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
3781                false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
3782        // TODO: Switch to user app stacks here.
3783        int ret = mStackSupervisor.startActivities(null, uid, callingPackage, intents, resolvedTypes,
3784                resultTo, options, userId);
3785        return ret;
3786    }
3787
3788    //explicitly remove thd old information in mRecentTasks when removing existing user.
3789    private void removeRecentTasksForUserLocked(int userId) {
3790        if(userId <= 0) {
3791            Slog.i(TAG, "Can't remove recent task on user " + userId);
3792            return;
3793        }
3794
3795        for (int i = mRecentTasks.size() - 1; i >= 0; --i) {
3796            TaskRecord tr = mRecentTasks.get(i);
3797            if (tr.userId == userId) {
3798                if(DEBUG_TASKS) Slog.i(TAG, "remove RecentTask " + tr
3799                        + " when finishing user" + userId);
3800                mRecentTasks.remove(i);
3801                tr.removedFromRecents(mTaskPersister);
3802            }
3803        }
3804
3805        // Remove tasks from persistent storage.
3806        mTaskPersister.wakeup(null, true);
3807    }
3808
3809    /**
3810     * Update the recent tasks lists: make sure tasks should still be here (their
3811     * applications / activities still exist), update their availability, fixup ordering
3812     * of affiliations.
3813     */
3814    void cleanupRecentTasksLocked(int userId) {
3815        if (mRecentTasks == null) {
3816            // Happens when called from the packagemanager broadcast before boot.
3817            return;
3818        }
3819
3820        final HashMap<ComponentName, ActivityInfo> availActCache = new HashMap<>();
3821        final HashMap<String, ApplicationInfo> availAppCache = new HashMap<>();
3822        final IPackageManager pm = AppGlobals.getPackageManager();
3823        final ActivityInfo dummyAct = new ActivityInfo();
3824        final ApplicationInfo dummyApp = new ApplicationInfo();
3825
3826        int N = mRecentTasks.size();
3827
3828        int[] users = userId == UserHandle.USER_ALL
3829                ? getUsersLocked() : new int[] { userId };
3830        for (int user : users) {
3831            for (int i = 0; i < N; i++) {
3832                TaskRecord task = mRecentTasks.get(i);
3833                if (task.userId != user) {
3834                    // Only look at tasks for the user ID of interest.
3835                    continue;
3836                }
3837                if (task.autoRemoveRecents && task.getTopActivity() == null) {
3838                    // This situation is broken, and we should just get rid of it now.
3839                    mRecentTasks.remove(i);
3840                    task.removedFromRecents(mTaskPersister);
3841                    i--;
3842                    N--;
3843                    Slog.w(TAG, "Removing auto-remove without activity: " + task);
3844                    continue;
3845                }
3846                // Check whether this activity is currently available.
3847                if (task.realActivity != null) {
3848                    ActivityInfo ai = availActCache.get(task.realActivity);
3849                    if (ai == null) {
3850                        try {
3851                            ai = pm.getActivityInfo(task.realActivity,
3852                                    PackageManager.GET_UNINSTALLED_PACKAGES
3853                                    | PackageManager.GET_DISABLED_COMPONENTS, user);
3854                        } catch (RemoteException e) {
3855                            // Will never happen.
3856                            continue;
3857                        }
3858                        if (ai == null) {
3859                            ai = dummyAct;
3860                        }
3861                        availActCache.put(task.realActivity, ai);
3862                    }
3863                    if (ai == dummyAct) {
3864                        // This could be either because the activity no longer exists, or the
3865                        // app is temporarily gone.  For the former we want to remove the recents
3866                        // entry; for the latter we want to mark it as unavailable.
3867                        ApplicationInfo app = availAppCache.get(task.realActivity.getPackageName());
3868                        if (app == null) {
3869                            try {
3870                                app = pm.getApplicationInfo(task.realActivity.getPackageName(),
3871                                        PackageManager.GET_UNINSTALLED_PACKAGES
3872                                        | PackageManager.GET_DISABLED_COMPONENTS, user);
3873                            } catch (RemoteException e) {
3874                                // Will never happen.
3875                                continue;
3876                            }
3877                            if (app == null) {
3878                                app = dummyApp;
3879                            }
3880                            availAppCache.put(task.realActivity.getPackageName(), app);
3881                        }
3882                        if (app == dummyApp || (app.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3883                            // Doesn't exist any more!  Good-bye.
3884                            mRecentTasks.remove(i);
3885                            task.removedFromRecents(mTaskPersister);
3886                            i--;
3887                            N--;
3888                            Slog.w(TAG, "Removing no longer valid recent: " + task);
3889                            continue;
3890                        } else {
3891                            // Otherwise just not available for now.
3892                            if (task.isAvailable) {
3893                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3894                                        + task);
3895                            }
3896                            task.isAvailable = false;
3897                        }
3898                    } else {
3899                        if (!ai.enabled || !ai.applicationInfo.enabled
3900                                || (ai.applicationInfo.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
3901                            if (task.isAvailable) {
3902                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent unavailable: "
3903                                        + task + " (enabled=" + ai.enabled + "/"
3904                                        + ai.applicationInfo.enabled +  " flags="
3905                                        + Integer.toHexString(ai.applicationInfo.flags) + ")");
3906                            }
3907                            task.isAvailable = false;
3908                        } else {
3909                            if (!task.isAvailable) {
3910                                if (DEBUG_RECENTS) Slog.d(TAG, "Making recent available: "
3911                                        + task);
3912                            }
3913                            task.isAvailable = true;
3914                        }
3915                    }
3916                }
3917            }
3918        }
3919
3920        // Verify the affiliate chain for each task.
3921        for (int i = 0; i < N; ) {
3922            TaskRecord task = mRecentTasks.remove(i);
3923            if (mTmpRecents.contains(task)) {
3924                continue;
3925            }
3926            int affiliatedTaskId = task.mAffiliatedTaskId;
3927            while (true) {
3928                TaskRecord next = task.mNextAffiliate;
3929                if (next == null) {
3930                    break;
3931                }
3932                if (next.mAffiliatedTaskId != affiliatedTaskId) {
3933                    Slog.e(TAG, "Error in Recents: next.affiliatedTaskId=" +
3934                            next.mAffiliatedTaskId + " affiliatedTaskId=" + affiliatedTaskId);
3935                    task.setNextAffiliate(null);
3936                    if (next.mPrevAffiliate == task) {
3937                        next.setPrevAffiliate(null);
3938                    }
3939                    break;
3940                }
3941                if (next.mPrevAffiliate != task) {
3942                    Slog.e(TAG, "Error in Recents chain prev.mNextAffiliate=" +
3943                            next.mPrevAffiliate + " task=" + task);
3944                    next.setPrevAffiliate(null);
3945                    task.setNextAffiliate(null);
3946                    break;
3947                }
3948                if (!mRecentTasks.contains(next)) {
3949                    Slog.e(TAG, "Error in Recents: next=" + next + " not in mRecentTasks");
3950                    task.setNextAffiliate(null);
3951                    // We know that next.mPrevAffiliate is always task, from above, so clear
3952                    // its previous affiliate.
3953                    next.setPrevAffiliate(null);
3954                    break;
3955                }
3956                task = next;
3957            }
3958            // task is now the end of the list
3959            do {
3960                mRecentTasks.remove(task);
3961                mRecentTasks.add(i++, task);
3962                mTmpRecents.add(task);
3963                task.inRecents = true;
3964            } while ((task = task.mPrevAffiliate) != null);
3965        }
3966        mTmpRecents.clear();
3967        // mRecentTasks is now in sorted, affiliated order.
3968    }
3969
3970    private final boolean moveAffiliatedTasksToFront(TaskRecord task, int taskIndex) {
3971        int N = mRecentTasks.size();
3972        TaskRecord top = task;
3973        int topIndex = taskIndex;
3974        while (top.mNextAffiliate != null && topIndex > 0) {
3975            top = top.mNextAffiliate;
3976            topIndex--;
3977        }
3978        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding affilliates starting at "
3979                + topIndex + " from intial " + taskIndex);
3980        // Find the end of the chain, doing a sanity check along the way.
3981        boolean sane = top.mAffiliatedTaskId == task.mAffiliatedTaskId;
3982        int endIndex = topIndex;
3983        TaskRecord prev = top;
3984        while (endIndex < N) {
3985            TaskRecord cur = mRecentTasks.get(endIndex);
3986            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: looking at next chain @"
3987                    + endIndex + " " + cur);
3988            if (cur == top) {
3989                // Verify start of the chain.
3990                if (cur.mNextAffiliate != null || cur.mNextAffiliateTaskId != -1) {
3991                    Slog.wtf(TAG, "Bad chain @" + endIndex
3992                            + ": first task has next affiliate: " + prev);
3993                    sane = false;
3994                    break;
3995                }
3996            } else {
3997                // Verify middle of the chain's next points back to the one before.
3998                if (cur.mNextAffiliate != prev
3999                        || cur.mNextAffiliateTaskId != prev.taskId) {
4000                    Slog.wtf(TAG, "Bad chain @" + endIndex
4001                            + ": middle task " + cur + " @" + endIndex
4002                            + " has bad next affiliate "
4003                            + cur.mNextAffiliate + " id " + cur.mNextAffiliateTaskId
4004                            + ", expected " + prev);
4005                    sane = false;
4006                    break;
4007                }
4008            }
4009            if (cur.mPrevAffiliateTaskId == -1) {
4010                // Chain ends here.
4011                if (cur.mPrevAffiliate != null) {
4012                    Slog.wtf(TAG, "Bad chain @" + endIndex
4013                            + ": last task " + cur + " has previous affiliate "
4014                            + cur.mPrevAffiliate);
4015                    sane = false;
4016                }
4017                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: end of chain @" + endIndex);
4018                break;
4019            } else {
4020                // Verify middle of the chain's prev points to a valid item.
4021                if (cur.mPrevAffiliate == null) {
4022                    Slog.wtf(TAG, "Bad chain @" + endIndex
4023                            + ": task " + cur + " has previous affiliate "
4024                            + cur.mPrevAffiliate + " but should be id "
4025                            + cur.mPrevAffiliate);
4026                    sane = false;
4027                    break;
4028                }
4029            }
4030            if (cur.mAffiliatedTaskId != task.mAffiliatedTaskId) {
4031                Slog.wtf(TAG, "Bad chain @" + endIndex
4032                        + ": task " + cur + " has affiliated id "
4033                        + cur.mAffiliatedTaskId + " but should be "
4034                        + task.mAffiliatedTaskId);
4035                sane = false;
4036                break;
4037            }
4038            prev = cur;
4039            endIndex++;
4040            if (endIndex >= N) {
4041                Slog.wtf(TAG, "Bad chain ran off index " + endIndex
4042                        + ": last task " + prev);
4043                sane = false;
4044                break;
4045            }
4046        }
4047        if (sane) {
4048            if (endIndex < taskIndex) {
4049                Slog.wtf(TAG, "Bad chain @" + endIndex
4050                        + ": did not extend to task " + task + " @" + taskIndex);
4051                sane = false;
4052            }
4053        }
4054        if (sane) {
4055            // All looks good, we can just move all of the affiliated tasks
4056            // to the top.
4057            for (int i=topIndex; i<=endIndex; i++) {
4058                if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving affiliated " + task
4059                        + " from " + i + " to " + (i-topIndex));
4060                TaskRecord cur = mRecentTasks.remove(i);
4061                mRecentTasks.add(i-topIndex, cur);
4062            }
4063            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: done moving tasks  " +  topIndex
4064                    + " to " + endIndex);
4065            return true;
4066        }
4067
4068        // Whoops, couldn't do it.
4069        return false;
4070    }
4071
4072    final void addRecentTaskLocked(TaskRecord task) {
4073        final boolean isAffiliated = task.mAffiliatedTaskId != task.taskId
4074                || task.mNextAffiliateTaskId != -1 || task.mPrevAffiliateTaskId != -1;
4075
4076        int N = mRecentTasks.size();
4077        // Quick case: check if the top-most recent task is the same.
4078        if (!isAffiliated && N > 0 && mRecentTasks.get(0) == task) {
4079            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: already at top: " + task);
4080            return;
4081        }
4082        // Another quick case: check if this is part of a set of affiliated
4083        // tasks that are at the top.
4084        if (isAffiliated && N > 0 && task.inRecents
4085                && task.mAffiliatedTaskId == mRecentTasks.get(0).mAffiliatedTaskId) {
4086            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: affiliated " + mRecentTasks.get(0)
4087                    + " at top when adding " + task);
4088            return;
4089        }
4090        // Another quick case: never add voice sessions.
4091        if (task.voiceSession != null) {
4092            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: not adding voice interaction " + task);
4093            return;
4094        }
4095
4096        boolean needAffiliationFix = false;
4097
4098        // Slightly less quick case: the task is already in recents, so all we need
4099        // to do is move it.
4100        if (task.inRecents) {
4101            int taskIndex = mRecentTasks.indexOf(task);
4102            if (taskIndex >= 0) {
4103                if (!isAffiliated) {
4104                    // Simple case: this is not an affiliated task, so we just move it to the front.
4105                    mRecentTasks.remove(taskIndex);
4106                    mRecentTasks.add(0, task);
4107                    notifyTaskPersisterLocked(task, false);
4108                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: moving to top " + task
4109                            + " from " + taskIndex);
4110                    return;
4111                } else {
4112                    // More complicated: need to keep all affiliated tasks together.
4113                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4114                        // All went well.
4115                        return;
4116                    }
4117
4118                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4119                    // everything and then go through our general path of adding a new task.
4120                    needAffiliationFix = true;
4121                }
4122            } else {
4123                Slog.wtf(TAG, "Task with inRecent not in recents: " + task);
4124                needAffiliationFix = true;
4125            }
4126        }
4127
4128        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: trimming tasks for " + task);
4129        trimRecentsForTask(task, true);
4130
4131        N = mRecentTasks.size();
4132        while (N >= ActivityManager.getMaxRecentTasksStatic()) {
4133            final TaskRecord tr = mRecentTasks.remove(N - 1);
4134            tr.removedFromRecents(mTaskPersister);
4135            N--;
4136        }
4137        task.inRecents = true;
4138        if (!isAffiliated || needAffiliationFix) {
4139            // If this is a simple non-affiliated task, or we had some failure trying to
4140            // handle it as part of an affilated task, then just place it at the top.
4141            mRecentTasks.add(0, task);
4142        } else if (isAffiliated) {
4143            // If this is a new affiliated task, then move all of the affiliated tasks
4144            // to the front and insert this new one.
4145            TaskRecord other = task.mNextAffiliate;
4146            if (other == null) {
4147                other = task.mPrevAffiliate;
4148            }
4149            if (other != null) {
4150                int otherIndex = mRecentTasks.indexOf(other);
4151                if (otherIndex >= 0) {
4152                    // Insert new task at appropriate location.
4153                    int taskIndex;
4154                    if (other == task.mNextAffiliate) {
4155                        // We found the index of our next affiliation, which is who is
4156                        // before us in the list, so add after that point.
4157                        taskIndex = otherIndex+1;
4158                    } else {
4159                        // We found the index of our previous affiliation, which is who is
4160                        // after us in the list, so add at their position.
4161                        taskIndex = otherIndex;
4162                    }
4163                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: new affiliated task added at "
4164                            + taskIndex + ": " + task);
4165                    mRecentTasks.add(taskIndex, task);
4166
4167                    // Now move everything to the front.
4168                    if (moveAffiliatedTasksToFront(task, taskIndex)) {
4169                        // All went well.
4170                        return;
4171                    }
4172
4173                    // Uh oh...  something bad in the affiliation chain, try to rebuild
4174                    // everything and then go through our general path of adding a new task.
4175                    needAffiliationFix = true;
4176                } else {
4177                    if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: couldn't find other affiliation "
4178                            + other);
4179                    needAffiliationFix = true;
4180                }
4181            } else {
4182                if (DEBUG_RECENTS) Slog.d(TAG,
4183                        "addRecent: adding affiliated task without next/prev:" + task);
4184                needAffiliationFix = true;
4185            }
4186        }
4187        if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: adding " + task);
4188
4189        if (needAffiliationFix) {
4190            if (DEBUG_RECENTS) Slog.d(TAG, "addRecent: regrouping affiliations");
4191            cleanupRecentTasksLocked(task.userId);
4192        }
4193    }
4194
4195    /**
4196     * If needed, remove oldest existing entries in recents that are for the same kind
4197     * of task as the given one.
4198     */
4199    int trimRecentsForTask(TaskRecord task, boolean doTrim) {
4200        int N = mRecentTasks.size();
4201        final Intent intent = task.intent;
4202        final boolean document = intent != null && intent.isDocument();
4203
4204        int maxRecents = task.maxRecents - 1;
4205        for (int i=0; i<N; i++) {
4206            final TaskRecord tr = mRecentTasks.get(i);
4207            if (task != tr) {
4208                if (task.userId != tr.userId) {
4209                    continue;
4210                }
4211                if (i > MAX_RECENT_BITMAPS) {
4212                    tr.freeLastThumbnail();
4213                }
4214                final Intent trIntent = tr.intent;
4215                if ((task.affinity == null || !task.affinity.equals(tr.affinity)) &&
4216                    (intent == null || !intent.filterEquals(trIntent))) {
4217                    continue;
4218                }
4219                final boolean trIsDocument = trIntent != null && trIntent.isDocument();
4220                if (document && trIsDocument) {
4221                    // These are the same document activity (not necessarily the same doc).
4222                    if (maxRecents > 0) {
4223                        --maxRecents;
4224                        continue;
4225                    }
4226                    // Hit the maximum number of documents for this task. Fall through
4227                    // and remove this document from recents.
4228                } else if (document || trIsDocument) {
4229                    // Only one of these is a document. Not the droid we're looking for.
4230                    continue;
4231                }
4232            }
4233
4234            if (!doTrim) {
4235                // If the caller is not actually asking for a trim, just tell them we reached
4236                // a point where the trim would happen.
4237                return i;
4238            }
4239
4240            // Either task and tr are the same or, their affinities match or their intents match
4241            // and neither of them is a document, or they are documents using the same activity
4242            // and their maxRecents has been reached.
4243            tr.disposeThumbnail();
4244            mRecentTasks.remove(i);
4245            if (task != tr) {
4246                tr.removedFromRecents(mTaskPersister);
4247            }
4248            i--;
4249            N--;
4250            if (task.intent == null) {
4251                // If the new recent task we are adding is not fully
4252                // specified, then replace it with the existing recent task.
4253                task = tr;
4254            }
4255            notifyTaskPersisterLocked(tr, false);
4256        }
4257
4258        return -1;
4259    }
4260
4261    @Override
4262    public void reportActivityFullyDrawn(IBinder token) {
4263        synchronized (this) {
4264            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4265            if (r == null) {
4266                return;
4267            }
4268            r.reportFullyDrawnLocked();
4269        }
4270    }
4271
4272    @Override
4273    public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4274        synchronized (this) {
4275            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4276            if (r == null) {
4277                return;
4278            }
4279            final long origId = Binder.clearCallingIdentity();
4280            mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4281            Configuration config = mWindowManager.updateOrientationFromAppTokens(
4282                    mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4283            if (config != null) {
4284                r.frozenBeforeDestroy = true;
4285                if (!updateConfigurationLocked(config, r, false, false)) {
4286                    mStackSupervisor.resumeTopActivitiesLocked();
4287                }
4288            }
4289            Binder.restoreCallingIdentity(origId);
4290        }
4291    }
4292
4293    @Override
4294    public int getRequestedOrientation(IBinder token) {
4295        synchronized (this) {
4296            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4297            if (r == null) {
4298                return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4299            }
4300            return mWindowManager.getAppOrientation(r.appToken);
4301        }
4302    }
4303
4304    /**
4305     * This is the internal entry point for handling Activity.finish().
4306     *
4307     * @param token The Binder token referencing the Activity we want to finish.
4308     * @param resultCode Result code, if any, from this Activity.
4309     * @param resultData Result data (Intent), if any, from this Activity.
4310     * @param finishTask Whether to finish the task associated with this Activity.  Only applies to
4311     *            the root Activity in the task.
4312     *
4313     * @return Returns true if the activity successfully finished, or false if it is still running.
4314     */
4315    @Override
4316    public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4317            boolean finishTask) {
4318        // Refuse possible leaked file descriptors
4319        if (resultData != null && resultData.hasFileDescriptors() == true) {
4320            throw new IllegalArgumentException("File descriptors passed in Intent");
4321        }
4322
4323        synchronized(this) {
4324            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4325            if (r == null) {
4326                return true;
4327            }
4328            // Keep track of the root activity of the task before we finish it
4329            TaskRecord tr = r.task;
4330            ActivityRecord rootR = tr.getRootActivity();
4331            // Do not allow task to finish in Lock Task mode.
4332            if (tr == mStackSupervisor.mLockTaskModeTask) {
4333                if (rootR == r) {
4334                    mStackSupervisor.showLockTaskToast();
4335                    return false;
4336                }
4337            }
4338            if (mController != null) {
4339                // Find the first activity that is not finishing.
4340                ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4341                if (next != null) {
4342                    // ask watcher if this is allowed
4343                    boolean resumeOK = true;
4344                    try {
4345                        resumeOK = mController.activityResuming(next.packageName);
4346                    } catch (RemoteException e) {
4347                        mController = null;
4348                        Watchdog.getInstance().setActivityController(null);
4349                    }
4350
4351                    if (!resumeOK) {
4352                        return false;
4353                    }
4354                }
4355            }
4356            final long origId = Binder.clearCallingIdentity();
4357            try {
4358                boolean res;
4359                if (finishTask && r == rootR) {
4360                    // If requested, remove the task that is associated to this activity only if it
4361                    // was the root activity in the task.  The result code and data is ignored because
4362                    // we don't support returning them across task boundaries.
4363                    res = removeTaskByIdLocked(tr.taskId, 0);
4364                } else {
4365                    res = tr.stack.requestFinishActivityLocked(token, resultCode,
4366                            resultData, "app-request", true);
4367                }
4368                return res;
4369            } finally {
4370                Binder.restoreCallingIdentity(origId);
4371            }
4372        }
4373    }
4374
4375    @Override
4376    public final void finishHeavyWeightApp() {
4377        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4378                != PackageManager.PERMISSION_GRANTED) {
4379            String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4380                    + Binder.getCallingPid()
4381                    + ", uid=" + Binder.getCallingUid()
4382                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4383            Slog.w(TAG, msg);
4384            throw new SecurityException(msg);
4385        }
4386
4387        synchronized(this) {
4388            if (mHeavyWeightProcess == null) {
4389                return;
4390            }
4391
4392            ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
4393                    mHeavyWeightProcess.activities);
4394            for (int i=0; i<activities.size(); i++) {
4395                ActivityRecord r = activities.get(i);
4396                if (!r.finishing) {
4397                    r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4398                            null, "finish-heavy", true);
4399                }
4400            }
4401
4402            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4403                    mHeavyWeightProcess.userId, 0));
4404            mHeavyWeightProcess = null;
4405        }
4406    }
4407
4408    @Override
4409    public void crashApplication(int uid, int initialPid, String packageName,
4410            String message) {
4411        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4412                != PackageManager.PERMISSION_GRANTED) {
4413            String msg = "Permission Denial: crashApplication() from pid="
4414                    + Binder.getCallingPid()
4415                    + ", uid=" + Binder.getCallingUid()
4416                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4417            Slog.w(TAG, msg);
4418            throw new SecurityException(msg);
4419        }
4420
4421        synchronized(this) {
4422            ProcessRecord proc = null;
4423
4424            // Figure out which process to kill.  We don't trust that initialPid
4425            // still has any relation to current pids, so must scan through the
4426            // list.
4427            synchronized (mPidsSelfLocked) {
4428                for (int i=0; i<mPidsSelfLocked.size(); i++) {
4429                    ProcessRecord p = mPidsSelfLocked.valueAt(i);
4430                    if (p.uid != uid) {
4431                        continue;
4432                    }
4433                    if (p.pid == initialPid) {
4434                        proc = p;
4435                        break;
4436                    }
4437                    if (p.pkgList.containsKey(packageName)) {
4438                        proc = p;
4439                    }
4440                }
4441            }
4442
4443            if (proc == null) {
4444                Slog.w(TAG, "crashApplication: nothing for uid=" + uid
4445                        + " initialPid=" + initialPid
4446                        + " packageName=" + packageName);
4447                return;
4448            }
4449
4450            if (proc.thread != null) {
4451                if (proc.pid == Process.myPid()) {
4452                    Log.w(TAG, "crashApplication: trying to crash self!");
4453                    return;
4454                }
4455                long ident = Binder.clearCallingIdentity();
4456                try {
4457                    proc.thread.scheduleCrash(message);
4458                } catch (RemoteException e) {
4459                }
4460                Binder.restoreCallingIdentity(ident);
4461            }
4462        }
4463    }
4464
4465    @Override
4466    public final void finishSubActivity(IBinder token, String resultWho,
4467            int requestCode) {
4468        synchronized(this) {
4469            final long origId = Binder.clearCallingIdentity();
4470            ActivityRecord r = ActivityRecord.isInStackLocked(token);
4471            if (r != null) {
4472                r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4473            }
4474            Binder.restoreCallingIdentity(origId);
4475        }
4476    }
4477
4478    @Override
4479    public boolean finishActivityAffinity(IBinder token) {
4480        synchronized(this) {
4481            final long origId = Binder.clearCallingIdentity();
4482            try {
4483                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4484
4485                ActivityRecord rootR = r.task.getRootActivity();
4486                // Do not allow task to finish in Lock Task mode.
4487                if (r.task == mStackSupervisor.mLockTaskModeTask) {
4488                    if (rootR == r) {
4489                        mStackSupervisor.showLockTaskToast();
4490                        return false;
4491                    }
4492                }
4493                boolean res = false;
4494                if (r != null) {
4495                    res = r.task.stack.finishActivityAffinityLocked(r);
4496                }
4497                return res;
4498            } finally {
4499                Binder.restoreCallingIdentity(origId);
4500            }
4501        }
4502    }
4503
4504    @Override
4505    public void finishVoiceTask(IVoiceInteractionSession session) {
4506        synchronized(this) {
4507            final long origId = Binder.clearCallingIdentity();
4508            try {
4509                mStackSupervisor.finishVoiceTask(session);
4510            } finally {
4511                Binder.restoreCallingIdentity(origId);
4512            }
4513        }
4514
4515    }
4516
4517    @Override
4518    public boolean releaseActivityInstance(IBinder token) {
4519        synchronized(this) {
4520            final long origId = Binder.clearCallingIdentity();
4521            try {
4522                ActivityRecord r = ActivityRecord.isInStackLocked(token);
4523                if (r.task == null || r.task.stack == null) {
4524                    return false;
4525                }
4526                return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4527            } finally {
4528                Binder.restoreCallingIdentity(origId);
4529            }
4530        }
4531    }
4532
4533    @Override
4534    public void releaseSomeActivities(IApplicationThread appInt) {
4535        synchronized(this) {
4536            final long origId = Binder.clearCallingIdentity();
4537            try {
4538                ProcessRecord app = getRecordForAppLocked(appInt);
4539                mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4540            } finally {
4541                Binder.restoreCallingIdentity(origId);
4542            }
4543        }
4544    }
4545
4546    @Override
4547    public boolean willActivityBeVisible(IBinder token) {
4548        synchronized(this) {
4549            ActivityStack stack = ActivityRecord.getStackLocked(token);
4550            if (stack != null) {
4551                return stack.willActivityBeVisibleLocked(token);
4552            }
4553            return false;
4554        }
4555    }
4556
4557    @Override
4558    public void overridePendingTransition(IBinder token, String packageName,
4559            int enterAnim, int exitAnim) {
4560        synchronized(this) {
4561            ActivityRecord self = ActivityRecord.isInStackLocked(token);
4562            if (self == null) {
4563                return;
4564            }
4565
4566            final long origId = Binder.clearCallingIdentity();
4567
4568            if (self.state == ActivityState.RESUMED
4569                    || self.state == ActivityState.PAUSING) {
4570                mWindowManager.overridePendingAppTransition(packageName,
4571                        enterAnim, exitAnim, null);
4572            }
4573
4574            Binder.restoreCallingIdentity(origId);
4575        }
4576    }
4577
4578    /**
4579     * Main function for removing an existing process from the activity manager
4580     * as a result of that process going away.  Clears out all connections
4581     * to the process.
4582     */
4583    private final void handleAppDiedLocked(ProcessRecord app,
4584            boolean restarting, boolean allowRestart) {
4585        int pid = app.pid;
4586        cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4587        if (!restarting) {
4588            removeLruProcessLocked(app);
4589            if (pid > 0) {
4590                ProcessList.remove(pid);
4591            }
4592        }
4593
4594        if (mProfileProc == app) {
4595            clearProfilerLocked();
4596        }
4597
4598        // Remove this application's activities from active lists.
4599        boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4600
4601        app.activities.clear();
4602
4603        if (app.instrumentationClass != null) {
4604            Slog.w(TAG, "Crash of app " + app.processName
4605                  + " running instrumentation " + app.instrumentationClass);
4606            Bundle info = new Bundle();
4607            info.putString("shortMsg", "Process crashed.");
4608            finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4609        }
4610
4611        if (!restarting) {
4612            if (!mStackSupervisor.resumeTopActivitiesLocked()) {
4613                // If there was nothing to resume, and we are not already
4614                // restarting this process, but there is a visible activity that
4615                // is hosted by the process...  then make sure all visible
4616                // activities are running, taking care of restarting this
4617                // process.
4618                if (hasVisibleActivities) {
4619                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
4620                }
4621            }
4622        }
4623    }
4624
4625    private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4626        IBinder threadBinder = thread.asBinder();
4627        // Find the application record.
4628        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4629            ProcessRecord rec = mLruProcesses.get(i);
4630            if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4631                return i;
4632            }
4633        }
4634        return -1;
4635    }
4636
4637    final ProcessRecord getRecordForAppLocked(
4638            IApplicationThread thread) {
4639        if (thread == null) {
4640            return null;
4641        }
4642
4643        int appIndex = getLRURecordIndexForAppLocked(thread);
4644        return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4645    }
4646
4647    final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4648        // If there are no longer any background processes running,
4649        // and the app that died was not running instrumentation,
4650        // then tell everyone we are now low on memory.
4651        boolean haveBg = false;
4652        for (int i=mLruProcesses.size()-1; i>=0; i--) {
4653            ProcessRecord rec = mLruProcesses.get(i);
4654            if (rec.thread != null
4655                    && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4656                haveBg = true;
4657                break;
4658            }
4659        }
4660
4661        if (!haveBg) {
4662            boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4663            if (doReport) {
4664                long now = SystemClock.uptimeMillis();
4665                if (now < (mLastMemUsageReportTime+5*60*1000)) {
4666                    doReport = false;
4667                } else {
4668                    mLastMemUsageReportTime = now;
4669                }
4670            }
4671            final ArrayList<ProcessMemInfo> memInfos
4672                    = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4673            EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4674            long now = SystemClock.uptimeMillis();
4675            for (int i=mLruProcesses.size()-1; i>=0; i--) {
4676                ProcessRecord rec = mLruProcesses.get(i);
4677                if (rec == dyingProc || rec.thread == null) {
4678                    continue;
4679                }
4680                if (doReport) {
4681                    memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4682                            rec.setProcState, rec.adjType, rec.makeAdjReason()));
4683                }
4684                if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4685                    // The low memory report is overriding any current
4686                    // state for a GC request.  Make sure to do
4687                    // heavy/important/visible/foreground processes first.
4688                    if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4689                        rec.lastRequestedGc = 0;
4690                    } else {
4691                        rec.lastRequestedGc = rec.lastLowMemory;
4692                    }
4693                    rec.reportLowMemory = true;
4694                    rec.lastLowMemory = now;
4695                    mProcessesToGc.remove(rec);
4696                    addProcessToGcListLocked(rec);
4697                }
4698            }
4699            if (doReport) {
4700                Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4701                mHandler.sendMessage(msg);
4702            }
4703            scheduleAppGcsLocked();
4704        }
4705    }
4706
4707    final void appDiedLocked(ProcessRecord app) {
4708       appDiedLocked(app, app.pid, app.thread);
4709    }
4710
4711    final void appDiedLocked(ProcessRecord app, int pid,
4712            IApplicationThread thread) {
4713
4714        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
4715        synchronized (stats) {
4716            stats.noteProcessDiedLocked(app.info.uid, pid);
4717        }
4718
4719        Process.killProcessGroup(app.info.uid, pid);
4720
4721        // Clean up already done if the process has been re-started.
4722        if (app.pid == pid && app.thread != null &&
4723                app.thread.asBinder() == thread.asBinder()) {
4724            boolean doLowMem = app.instrumentationClass == null;
4725            boolean doOomAdj = doLowMem;
4726            if (!app.killedByAm) {
4727                Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4728                        + ") has died.");
4729                mAllowLowerMemLevel = true;
4730            } else {
4731                // Note that we always want to do oom adj to update our state with the
4732                // new number of procs.
4733                mAllowLowerMemLevel = false;
4734                doLowMem = false;
4735            }
4736            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4737            if (DEBUG_CLEANUP) Slog.v(
4738                TAG, "Dying app: " + app + ", pid: " + pid
4739                + ", thread: " + thread.asBinder());
4740            handleAppDiedLocked(app, false, true);
4741
4742            if (doOomAdj) {
4743                updateOomAdjLocked();
4744            }
4745            if (doLowMem) {
4746                doLowMemReportIfNeededLocked(app);
4747            }
4748        } else if (app.pid != pid) {
4749            // A new process has already been started.
4750            Slog.i(TAG, "Process " + app.processName + " (pid " + pid
4751                    + ") has died and restarted (pid " + app.pid + ").");
4752            EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
4753        } else if (DEBUG_PROCESSES) {
4754            Slog.d(TAG, "Received spurious death notification for thread "
4755                    + thread.asBinder());
4756        }
4757    }
4758
4759    /**
4760     * If a stack trace dump file is configured, dump process stack traces.
4761     * @param clearTraces causes the dump file to be erased prior to the new
4762     *    traces being written, if true; when false, the new traces will be
4763     *    appended to any existing file content.
4764     * @param firstPids of dalvik VM processes to dump stack traces for first
4765     * @param lastPids of dalvik VM processes to dump stack traces for last
4766     * @param nativeProcs optional list of native process names to dump stack crawls
4767     * @return file containing stack traces, or null if no dump file is configured
4768     */
4769    public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
4770            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4771        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4772        if (tracesPath == null || tracesPath.length() == 0) {
4773            return null;
4774        }
4775
4776        File tracesFile = new File(tracesPath);
4777        try {
4778            File tracesDir = tracesFile.getParentFile();
4779            if (!tracesDir.exists()) {
4780                tracesFile.mkdirs();
4781                if (!SELinux.restorecon(tracesDir)) {
4782                    return null;
4783                }
4784            }
4785            FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4786
4787            if (clearTraces && tracesFile.exists()) tracesFile.delete();
4788            tracesFile.createNewFile();
4789            FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4790        } catch (IOException e) {
4791            Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
4792            return null;
4793        }
4794
4795        dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
4796        return tracesFile;
4797    }
4798
4799    private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
4800            ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
4801        // Use a FileObserver to detect when traces finish writing.
4802        // The order of traces is considered important to maintain for legibility.
4803        FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
4804            @Override
4805            public synchronized void onEvent(int event, String path) { notify(); }
4806        };
4807
4808        try {
4809            observer.startWatching();
4810
4811            // First collect all of the stacks of the most important pids.
4812            if (firstPids != null) {
4813                try {
4814                    int num = firstPids.size();
4815                    for (int i = 0; i < num; i++) {
4816                        synchronized (observer) {
4817                            Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
4818                            observer.wait(200);  // Wait for write-close, give up after 200msec
4819                        }
4820                    }
4821                } catch (InterruptedException e) {
4822                    Log.wtf(TAG, e);
4823                }
4824            }
4825
4826            // Next collect the stacks of the native pids
4827            if (nativeProcs != null) {
4828                int[] pids = Process.getPidsForCommands(nativeProcs);
4829                if (pids != null) {
4830                    for (int pid : pids) {
4831                        Debug.dumpNativeBacktraceToFile(pid, tracesPath);
4832                    }
4833                }
4834            }
4835
4836            // Lastly, measure CPU usage.
4837            if (processCpuTracker != null) {
4838                processCpuTracker.init();
4839                System.gc();
4840                processCpuTracker.update();
4841                try {
4842                    synchronized (processCpuTracker) {
4843                        processCpuTracker.wait(500); // measure over 1/2 second.
4844                    }
4845                } catch (InterruptedException e) {
4846                }
4847                processCpuTracker.update();
4848
4849                // We'll take the stack crawls of just the top apps using CPU.
4850                final int N = processCpuTracker.countWorkingStats();
4851                int numProcs = 0;
4852                for (int i=0; i<N && numProcs<5; i++) {
4853                    ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
4854                    if (lastPids.indexOfKey(stats.pid) >= 0) {
4855                        numProcs++;
4856                        try {
4857                            synchronized (observer) {
4858                                Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
4859                                observer.wait(200);  // Wait for write-close, give up after 200msec
4860                            }
4861                        } catch (InterruptedException e) {
4862                            Log.wtf(TAG, e);
4863                        }
4864
4865                    }
4866                }
4867            }
4868        } finally {
4869            observer.stopWatching();
4870        }
4871    }
4872
4873    final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
4874        if (true || IS_USER_BUILD) {
4875            return;
4876        }
4877        String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
4878        if (tracesPath == null || tracesPath.length() == 0) {
4879            return;
4880        }
4881
4882        StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
4883        StrictMode.allowThreadDiskWrites();
4884        try {
4885            final File tracesFile = new File(tracesPath);
4886            final File tracesDir = tracesFile.getParentFile();
4887            final File tracesTmp = new File(tracesDir, "__tmp__");
4888            try {
4889                if (!tracesDir.exists()) {
4890                    tracesFile.mkdirs();
4891                    if (!SELinux.restorecon(tracesDir.getPath())) {
4892                        return;
4893                    }
4894                }
4895                FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1);  // drwxrwxr-x
4896
4897                if (tracesFile.exists()) {
4898                    tracesTmp.delete();
4899                    tracesFile.renameTo(tracesTmp);
4900                }
4901                StringBuilder sb = new StringBuilder();
4902                Time tobj = new Time();
4903                tobj.set(System.currentTimeMillis());
4904                sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
4905                sb.append(": ");
4906                TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
4907                sb.append(" since ");
4908                sb.append(msg);
4909                FileOutputStream fos = new FileOutputStream(tracesFile);
4910                fos.write(sb.toString().getBytes());
4911                if (app == null) {
4912                    fos.write("\n*** No application process!".getBytes());
4913                }
4914                fos.close();
4915                FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
4916            } catch (IOException e) {
4917                Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
4918                return;
4919            }
4920
4921            if (app != null) {
4922                ArrayList<Integer> firstPids = new ArrayList<Integer>();
4923                firstPids.add(app.pid);
4924                dumpStackTraces(tracesPath, firstPids, null, null, null);
4925            }
4926
4927            File lastTracesFile = null;
4928            File curTracesFile = null;
4929            for (int i=9; i>=0; i--) {
4930                String name = String.format(Locale.US, "slow%02d.txt", i);
4931                curTracesFile = new File(tracesDir, name);
4932                if (curTracesFile.exists()) {
4933                    if (lastTracesFile != null) {
4934                        curTracesFile.renameTo(lastTracesFile);
4935                    } else {
4936                        curTracesFile.delete();
4937                    }
4938                }
4939                lastTracesFile = curTracesFile;
4940            }
4941            tracesFile.renameTo(curTracesFile);
4942            if (tracesTmp.exists()) {
4943                tracesTmp.renameTo(tracesFile);
4944            }
4945        } finally {
4946            StrictMode.setThreadPolicy(oldPolicy);
4947        }
4948    }
4949
4950    final void appNotResponding(ProcessRecord app, ActivityRecord activity,
4951            ActivityRecord parent, boolean aboveSystem, final String annotation) {
4952        ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
4953        SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
4954
4955        if (mController != null) {
4956            try {
4957                // 0 == continue, -1 = kill process immediately
4958                int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
4959                if (res < 0 && app.pid != MY_PID) {
4960                    app.kill("anr", true);
4961                }
4962            } catch (RemoteException e) {
4963                mController = null;
4964                Watchdog.getInstance().setActivityController(null);
4965            }
4966        }
4967
4968        long anrTime = SystemClock.uptimeMillis();
4969        if (MONITOR_CPU_USAGE) {
4970            updateCpuStatsNow();
4971        }
4972
4973        synchronized (this) {
4974            // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
4975            if (mShuttingDown) {
4976                Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
4977                return;
4978            } else if (app.notResponding) {
4979                Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
4980                return;
4981            } else if (app.crashing) {
4982                Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
4983                return;
4984            }
4985
4986            // In case we come through here for the same app before completing
4987            // this one, mark as anring now so we will bail out.
4988            app.notResponding = true;
4989
4990            // Log the ANR to the event log.
4991            EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
4992                    app.processName, app.info.flags, annotation);
4993
4994            // Dump thread traces as quickly as we can, starting with "interesting" processes.
4995            firstPids.add(app.pid);
4996
4997            int parentPid = app.pid;
4998            if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
4999            if (parentPid != app.pid) firstPids.add(parentPid);
5000
5001            if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
5002
5003            for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
5004                ProcessRecord r = mLruProcesses.get(i);
5005                if (r != null && r.thread != null) {
5006                    int pid = r.pid;
5007                    if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
5008                        if (r.persistent) {
5009                            firstPids.add(pid);
5010                        } else {
5011                            lastPids.put(pid, Boolean.TRUE);
5012                        }
5013                    }
5014                }
5015            }
5016        }
5017
5018        // Log the ANR to the main log.
5019        StringBuilder info = new StringBuilder();
5020        info.setLength(0);
5021        info.append("ANR in ").append(app.processName);
5022        if (activity != null && activity.shortComponentName != null) {
5023            info.append(" (").append(activity.shortComponentName).append(")");
5024        }
5025        info.append("\n");
5026        info.append("PID: ").append(app.pid).append("\n");
5027        if (annotation != null) {
5028            info.append("Reason: ").append(annotation).append("\n");
5029        }
5030        if (parent != null && parent != activity) {
5031            info.append("Parent: ").append(parent.shortComponentName).append("\n");
5032        }
5033
5034        final ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(true);
5035
5036        File tracesFile = dumpStackTraces(true, firstPids, processCpuTracker, lastPids,
5037                NATIVE_STACKS_OF_INTEREST);
5038
5039        String cpuInfo = null;
5040        if (MONITOR_CPU_USAGE) {
5041            updateCpuStatsNow();
5042            synchronized (mProcessCpuThread) {
5043                cpuInfo = mProcessCpuTracker.printCurrentState(anrTime);
5044            }
5045            info.append(processCpuTracker.printCurrentLoad());
5046            info.append(cpuInfo);
5047        }
5048
5049        info.append(processCpuTracker.printCurrentState(anrTime));
5050
5051        Slog.e(TAG, info.toString());
5052        if (tracesFile == null) {
5053            // There is no trace file, so dump (only) the alleged culprit's threads to the log
5054            Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
5055        }
5056
5057        addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
5058                cpuInfo, tracesFile, null);
5059
5060        if (mController != null) {
5061            try {
5062                // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
5063                int res = mController.appNotResponding(app.processName, app.pid, info.toString());
5064                if (res != 0) {
5065                    if (res < 0 && app.pid != MY_PID) {
5066                        app.kill("anr", true);
5067                    } else {
5068                        synchronized (this) {
5069                            mServices.scheduleServiceTimeoutLocked(app);
5070                        }
5071                    }
5072                    return;
5073                }
5074            } catch (RemoteException e) {
5075                mController = null;
5076                Watchdog.getInstance().setActivityController(null);
5077            }
5078        }
5079
5080        // Unless configured otherwise, swallow ANRs in background processes & kill the process.
5081        boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
5082                Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
5083
5084        synchronized (this) {
5085            if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
5086                app.kill("bg anr", true);
5087                return;
5088            }
5089
5090            // Set the app's notResponding state, and look up the errorReportReceiver
5091            makeAppNotRespondingLocked(app,
5092                    activity != null ? activity.shortComponentName : null,
5093                    annotation != null ? "ANR " + annotation : "ANR",
5094                    info.toString());
5095
5096            // Bring up the infamous App Not Responding dialog
5097            Message msg = Message.obtain();
5098            HashMap<String, Object> map = new HashMap<String, Object>();
5099            msg.what = SHOW_NOT_RESPONDING_MSG;
5100            msg.obj = map;
5101            msg.arg1 = aboveSystem ? 1 : 0;
5102            map.put("app", app);
5103            if (activity != null) {
5104                map.put("activity", activity);
5105            }
5106
5107            mHandler.sendMessage(msg);
5108        }
5109    }
5110
5111    final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5112        if (!mLaunchWarningShown) {
5113            mLaunchWarningShown = true;
5114            mHandler.post(new Runnable() {
5115                @Override
5116                public void run() {
5117                    synchronized (ActivityManagerService.this) {
5118                        final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5119                        d.show();
5120                        mHandler.postDelayed(new Runnable() {
5121                            @Override
5122                            public void run() {
5123                                synchronized (ActivityManagerService.this) {
5124                                    d.dismiss();
5125                                    mLaunchWarningShown = false;
5126                                }
5127                            }
5128                        }, 4000);
5129                    }
5130                }
5131            });
5132        }
5133    }
5134
5135    @Override
5136    public boolean clearApplicationUserData(final String packageName,
5137            final IPackageDataObserver observer, int userId) {
5138        enforceNotIsolatedCaller("clearApplicationUserData");
5139        int uid = Binder.getCallingUid();
5140        int pid = Binder.getCallingPid();
5141        userId = handleIncomingUser(pid, uid,
5142                userId, false, ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5143        long callingId = Binder.clearCallingIdentity();
5144        try {
5145            IPackageManager pm = AppGlobals.getPackageManager();
5146            int pkgUid = -1;
5147            synchronized(this) {
5148                try {
5149                    pkgUid = pm.getPackageUid(packageName, userId);
5150                } catch (RemoteException e) {
5151                }
5152                if (pkgUid == -1) {
5153                    Slog.w(TAG, "Invalid packageName: " + packageName);
5154                    if (observer != null) {
5155                        try {
5156                            observer.onRemoveCompleted(packageName, false);
5157                        } catch (RemoteException e) {
5158                            Slog.i(TAG, "Observer no longer exists.");
5159                        }
5160                    }
5161                    return false;
5162                }
5163                if (uid == pkgUid || checkComponentPermission(
5164                        android.Manifest.permission.CLEAR_APP_USER_DATA,
5165                        pid, uid, -1, true)
5166                        == PackageManager.PERMISSION_GRANTED) {
5167                    forceStopPackageLocked(packageName, pkgUid, "clear data");
5168                } else {
5169                    throw new SecurityException("PID " + pid + " does not have permission "
5170                            + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5171                                    + " of package " + packageName);
5172                }
5173
5174                // Remove all tasks match the cleared application package and user
5175                for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5176                    final TaskRecord tr = mRecentTasks.get(i);
5177                    final String taskPackageName =
5178                            tr.getBaseIntent().getComponent().getPackageName();
5179                    if (tr.userId != userId) continue;
5180                    if (!taskPackageName.equals(packageName)) continue;
5181                    removeTaskByIdLocked(tr.taskId, 0);
5182                }
5183            }
5184
5185            try {
5186                // Clear application user data
5187                pm.clearApplicationUserData(packageName, observer, userId);
5188
5189                synchronized(this) {
5190                    // Remove all permissions granted from/to this package
5191                    removeUriPermissionsForPackageLocked(packageName, userId, true);
5192                }
5193
5194                Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5195                        Uri.fromParts("package", packageName, null));
5196                intent.putExtra(Intent.EXTRA_UID, pkgUid);
5197                broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5198                        null, null, 0, null, null, null, false, false, userId);
5199            } catch (RemoteException e) {
5200            }
5201        } finally {
5202            Binder.restoreCallingIdentity(callingId);
5203        }
5204        return true;
5205    }
5206
5207    @Override
5208    public void killBackgroundProcesses(final String packageName, int userId) {
5209        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5210                != PackageManager.PERMISSION_GRANTED &&
5211                checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5212                        != PackageManager.PERMISSION_GRANTED) {
5213            String msg = "Permission Denial: killBackgroundProcesses() from pid="
5214                    + Binder.getCallingPid()
5215                    + ", uid=" + Binder.getCallingUid()
5216                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5217            Slog.w(TAG, msg);
5218            throw new SecurityException(msg);
5219        }
5220
5221        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5222                userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5223        long callingId = Binder.clearCallingIdentity();
5224        try {
5225            IPackageManager pm = AppGlobals.getPackageManager();
5226            synchronized(this) {
5227                int appId = -1;
5228                try {
5229                    appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
5230                } catch (RemoteException e) {
5231                }
5232                if (appId == -1) {
5233                    Slog.w(TAG, "Invalid packageName: " + packageName);
5234                    return;
5235                }
5236                killPackageProcessesLocked(packageName, appId, userId,
5237                        ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5238            }
5239        } finally {
5240            Binder.restoreCallingIdentity(callingId);
5241        }
5242    }
5243
5244    @Override
5245    public void killAllBackgroundProcesses() {
5246        if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5247                != PackageManager.PERMISSION_GRANTED) {
5248            String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5249                    + Binder.getCallingPid()
5250                    + ", uid=" + Binder.getCallingUid()
5251                    + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5252            Slog.w(TAG, msg);
5253            throw new SecurityException(msg);
5254        }
5255
5256        long callingId = Binder.clearCallingIdentity();
5257        try {
5258            synchronized(this) {
5259                ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5260                final int NP = mProcessNames.getMap().size();
5261                for (int ip=0; ip<NP; ip++) {
5262                    SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5263                    final int NA = apps.size();
5264                    for (int ia=0; ia<NA; ia++) {
5265                        ProcessRecord app = apps.valueAt(ia);
5266                        if (app.persistent) {
5267                            // we don't kill persistent processes
5268                            continue;
5269                        }
5270                        if (app.removed) {
5271                            procs.add(app);
5272                        } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5273                            app.removed = true;
5274                            procs.add(app);
5275                        }
5276                    }
5277                }
5278
5279                int N = procs.size();
5280                for (int i=0; i<N; i++) {
5281                    removeProcessLocked(procs.get(i), false, true, "kill all background");
5282                }
5283                mAllowLowerMemLevel = true;
5284                updateOomAdjLocked();
5285                doLowMemReportIfNeededLocked(null);
5286            }
5287        } finally {
5288            Binder.restoreCallingIdentity(callingId);
5289        }
5290    }
5291
5292    @Override
5293    public void forceStopPackage(final String packageName, int userId) {
5294        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5295                != PackageManager.PERMISSION_GRANTED) {
5296            String msg = "Permission Denial: forceStopPackage() from pid="
5297                    + Binder.getCallingPid()
5298                    + ", uid=" + Binder.getCallingUid()
5299                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5300            Slog.w(TAG, msg);
5301            throw new SecurityException(msg);
5302        }
5303        final int callingPid = Binder.getCallingPid();
5304        userId = handleIncomingUser(callingPid, Binder.getCallingUid(),
5305                userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5306        long callingId = Binder.clearCallingIdentity();
5307        try {
5308            IPackageManager pm = AppGlobals.getPackageManager();
5309            synchronized(this) {
5310                int[] users = userId == UserHandle.USER_ALL
5311                        ? getUsersLocked() : new int[] { userId };
5312                for (int user : users) {
5313                    int pkgUid = -1;
5314                    try {
5315                        pkgUid = pm.getPackageUid(packageName, user);
5316                    } catch (RemoteException e) {
5317                    }
5318                    if (pkgUid == -1) {
5319                        Slog.w(TAG, "Invalid packageName: " + packageName);
5320                        continue;
5321                    }
5322                    try {
5323                        pm.setPackageStoppedState(packageName, true, user);
5324                    } catch (RemoteException e) {
5325                    } catch (IllegalArgumentException e) {
5326                        Slog.w(TAG, "Failed trying to unstop package "
5327                                + packageName + ": " + e);
5328                    }
5329                    if (isUserRunningLocked(user, false)) {
5330                        forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5331                    }
5332                }
5333            }
5334        } finally {
5335            Binder.restoreCallingIdentity(callingId);
5336        }
5337    }
5338
5339    @Override
5340    public void addPackageDependency(String packageName) {
5341        synchronized (this) {
5342            int callingPid = Binder.getCallingPid();
5343            if (callingPid == Process.myPid()) {
5344                //  Yeah, um, no.
5345                Slog.w(TAG, "Can't addPackageDependency on system process");
5346                return;
5347            }
5348            ProcessRecord proc;
5349            synchronized (mPidsSelfLocked) {
5350                proc = mPidsSelfLocked.get(Binder.getCallingPid());
5351            }
5352            if (proc != null) {
5353                if (proc.pkgDeps == null) {
5354                    proc.pkgDeps = new ArraySet<String>(1);
5355                }
5356                proc.pkgDeps.add(packageName);
5357            }
5358        }
5359    }
5360
5361    /*
5362     * The pkg name and app id have to be specified.
5363     */
5364    @Override
5365    public void killApplicationWithAppId(String pkg, int appid, String reason) {
5366        if (pkg == null) {
5367            return;
5368        }
5369        // Make sure the uid is valid.
5370        if (appid < 0) {
5371            Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5372            return;
5373        }
5374        int callerUid = Binder.getCallingUid();
5375        // Only the system server can kill an application
5376        if (callerUid == Process.SYSTEM_UID) {
5377            // Post an aysnc message to kill the application
5378            Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5379            msg.arg1 = appid;
5380            msg.arg2 = 0;
5381            Bundle bundle = new Bundle();
5382            bundle.putString("pkg", pkg);
5383            bundle.putString("reason", reason);
5384            msg.obj = bundle;
5385            mHandler.sendMessage(msg);
5386        } else {
5387            throw new SecurityException(callerUid + " cannot kill pkg: " +
5388                    pkg);
5389        }
5390    }
5391
5392    @Override
5393    public void closeSystemDialogs(String reason) {
5394        enforceNotIsolatedCaller("closeSystemDialogs");
5395
5396        final int pid = Binder.getCallingPid();
5397        final int uid = Binder.getCallingUid();
5398        final long origId = Binder.clearCallingIdentity();
5399        try {
5400            synchronized (this) {
5401                // Only allow this from foreground processes, so that background
5402                // applications can't abuse it to prevent system UI from being shown.
5403                if (uid >= Process.FIRST_APPLICATION_UID) {
5404                    ProcessRecord proc;
5405                    synchronized (mPidsSelfLocked) {
5406                        proc = mPidsSelfLocked.get(pid);
5407                    }
5408                    if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5409                        Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5410                                + " from background process " + proc);
5411                        return;
5412                    }
5413                }
5414                closeSystemDialogsLocked(reason);
5415            }
5416        } finally {
5417            Binder.restoreCallingIdentity(origId);
5418        }
5419    }
5420
5421    void closeSystemDialogsLocked(String reason) {
5422        Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5423        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5424                | Intent.FLAG_RECEIVER_FOREGROUND);
5425        if (reason != null) {
5426            intent.putExtra("reason", reason);
5427        }
5428        mWindowManager.closeSystemDialogs(reason);
5429
5430        mStackSupervisor.closeSystemDialogsLocked();
5431
5432        broadcastIntentLocked(null, null, intent, null,
5433                null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
5434                Process.SYSTEM_UID, UserHandle.USER_ALL);
5435    }
5436
5437    @Override
5438    public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5439        enforceNotIsolatedCaller("getProcessMemoryInfo");
5440        Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5441        for (int i=pids.length-1; i>=0; i--) {
5442            ProcessRecord proc;
5443            int oomAdj;
5444            synchronized (this) {
5445                synchronized (mPidsSelfLocked) {
5446                    proc = mPidsSelfLocked.get(pids[i]);
5447                    oomAdj = proc != null ? proc.setAdj : 0;
5448                }
5449            }
5450            infos[i] = new Debug.MemoryInfo();
5451            Debug.getMemoryInfo(pids[i], infos[i]);
5452            if (proc != null) {
5453                synchronized (this) {
5454                    if (proc.thread != null && proc.setAdj == oomAdj) {
5455                        // Record this for posterity if the process has been stable.
5456                        proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5457                                infos[i].getTotalUss(), false, proc.pkgList);
5458                    }
5459                }
5460            }
5461        }
5462        return infos;
5463    }
5464
5465    @Override
5466    public long[] getProcessPss(int[] pids) {
5467        enforceNotIsolatedCaller("getProcessPss");
5468        long[] pss = new long[pids.length];
5469        for (int i=pids.length-1; i>=0; i--) {
5470            ProcessRecord proc;
5471            int oomAdj;
5472            synchronized (this) {
5473                synchronized (mPidsSelfLocked) {
5474                    proc = mPidsSelfLocked.get(pids[i]);
5475                    oomAdj = proc != null ? proc.setAdj : 0;
5476                }
5477            }
5478            long[] tmpUss = new long[1];
5479            pss[i] = Debug.getPss(pids[i], tmpUss);
5480            if (proc != null) {
5481                synchronized (this) {
5482                    if (proc.thread != null && proc.setAdj == oomAdj) {
5483                        // Record this for posterity if the process has been stable.
5484                        proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5485                    }
5486                }
5487            }
5488        }
5489        return pss;
5490    }
5491
5492    @Override
5493    public void killApplicationProcess(String processName, int uid) {
5494        if (processName == null) {
5495            return;
5496        }
5497
5498        int callerUid = Binder.getCallingUid();
5499        // Only the system server can kill an application
5500        if (callerUid == Process.SYSTEM_UID) {
5501            synchronized (this) {
5502                ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5503                if (app != null && app.thread != null) {
5504                    try {
5505                        app.thread.scheduleSuicide();
5506                    } catch (RemoteException e) {
5507                        // If the other end already died, then our work here is done.
5508                    }
5509                } else {
5510                    Slog.w(TAG, "Process/uid not found attempting kill of "
5511                            + processName + " / " + uid);
5512                }
5513            }
5514        } else {
5515            throw new SecurityException(callerUid + " cannot kill app process: " +
5516                    processName);
5517        }
5518    }
5519
5520    private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5521        forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5522                false, true, false, false, UserHandle.getUserId(uid), reason);
5523        Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5524                Uri.fromParts("package", packageName, null));
5525        if (!mProcessesReady) {
5526            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5527                    | Intent.FLAG_RECEIVER_FOREGROUND);
5528        }
5529        intent.putExtra(Intent.EXTRA_UID, uid);
5530        intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5531        broadcastIntentLocked(null, null, intent,
5532                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5533                false, false,
5534                MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5535    }
5536
5537    private void forceStopUserLocked(int userId, String reason) {
5538        forceStopPackageLocked(null, -1, false, false, true, false, false, userId, reason);
5539        Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
5540        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5541                | Intent.FLAG_RECEIVER_FOREGROUND);
5542        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
5543        broadcastIntentLocked(null, null, intent,
5544                null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5545                false, false,
5546                MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
5547    }
5548
5549    private final boolean killPackageProcessesLocked(String packageName, int appId,
5550            int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5551            boolean doit, boolean evenPersistent, String reason) {
5552        ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5553
5554        // Remove all processes this package may have touched: all with the
5555        // same UID (except for the system or root user), and all whose name
5556        // matches the package name.
5557        final int NP = mProcessNames.getMap().size();
5558        for (int ip=0; ip<NP; ip++) {
5559            SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5560            final int NA = apps.size();
5561            for (int ia=0; ia<NA; ia++) {
5562                ProcessRecord app = apps.valueAt(ia);
5563                if (app.persistent && !evenPersistent) {
5564                    // we don't kill persistent processes
5565                    continue;
5566                }
5567                if (app.removed) {
5568                    if (doit) {
5569                        procs.add(app);
5570                    }
5571                    continue;
5572                }
5573
5574                // Skip process if it doesn't meet our oom adj requirement.
5575                if (app.setAdj < minOomAdj) {
5576                    continue;
5577                }
5578
5579                // If no package is specified, we call all processes under the
5580                // give user id.
5581                if (packageName == null) {
5582                    if (app.userId != userId) {
5583                        continue;
5584                    }
5585                    if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5586                        continue;
5587                    }
5588                // Package has been specified, we want to hit all processes
5589                // that match it.  We need to qualify this by the processes
5590                // that are running under the specified app and user ID.
5591                } else {
5592                    final boolean isDep = app.pkgDeps != null
5593                            && app.pkgDeps.contains(packageName);
5594                    if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5595                        continue;
5596                    }
5597                    if (userId != UserHandle.USER_ALL && app.userId != userId) {
5598                        continue;
5599                    }
5600                    if (!app.pkgList.containsKey(packageName) && !isDep) {
5601                        continue;
5602                    }
5603                }
5604
5605                // Process has passed all conditions, kill it!
5606                if (!doit) {
5607                    return true;
5608                }
5609                app.removed = true;
5610                procs.add(app);
5611            }
5612        }
5613
5614        int N = procs.size();
5615        for (int i=0; i<N; i++) {
5616            removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5617        }
5618        updateOomAdjLocked();
5619        return N > 0;
5620    }
5621
5622    private final boolean forceStopPackageLocked(String name, int appId,
5623            boolean callerWillRestart, boolean purgeCache, boolean doit,
5624            boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5625        int i;
5626        int N;
5627
5628        if (userId == UserHandle.USER_ALL && name == null) {
5629            Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5630        }
5631
5632        if (appId < 0 && name != null) {
5633            try {
5634                appId = UserHandle.getAppId(
5635                        AppGlobals.getPackageManager().getPackageUid(name, 0));
5636            } catch (RemoteException e) {
5637            }
5638        }
5639
5640        if (doit) {
5641            if (name != null) {
5642                Slog.i(TAG, "Force stopping " + name + " appid=" + appId
5643                        + " user=" + userId + ": " + reason);
5644            } else {
5645                Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5646            }
5647
5648            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
5649            for (int ip=pmap.size()-1; ip>=0; ip--) {
5650                SparseArray<Long> ba = pmap.valueAt(ip);
5651                for (i=ba.size()-1; i>=0; i--) {
5652                    boolean remove = false;
5653                    final int entUid = ba.keyAt(i);
5654                    if (name != null) {
5655                        if (userId == UserHandle.USER_ALL) {
5656                            if (UserHandle.getAppId(entUid) == appId) {
5657                                remove = true;
5658                            }
5659                        } else {
5660                            if (entUid == UserHandle.getUid(userId, appId)) {
5661                                remove = true;
5662                            }
5663                        }
5664                    } else if (UserHandle.getUserId(entUid) == userId) {
5665                        remove = true;
5666                    }
5667                    if (remove) {
5668                        ba.removeAt(i);
5669                    }
5670                }
5671                if (ba.size() == 0) {
5672                    pmap.removeAt(ip);
5673                }
5674            }
5675        }
5676
5677        boolean didSomething = killPackageProcessesLocked(name, appId, userId,
5678                -100, callerWillRestart, true, doit, evenPersistent,
5679                name == null ? ("stop user " + userId) : ("stop " + name));
5680
5681        if (mStackSupervisor.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
5682            if (!doit) {
5683                return true;
5684            }
5685            didSomething = true;
5686        }
5687
5688        if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
5689            if (!doit) {
5690                return true;
5691            }
5692            didSomething = true;
5693        }
5694
5695        if (name == null) {
5696            // Remove all sticky broadcasts from this user.
5697            mStickyBroadcasts.remove(userId);
5698        }
5699
5700        ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
5701        if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
5702                userId, providers)) {
5703            if (!doit) {
5704                return true;
5705            }
5706            didSomething = true;
5707        }
5708        N = providers.size();
5709        for (i=0; i<N; i++) {
5710            removeDyingProviderLocked(null, providers.get(i), true);
5711        }
5712
5713        // Remove transient permissions granted from/to this package/user
5714        removeUriPermissionsForPackageLocked(name, userId, false);
5715
5716        if (name == null || uninstalling) {
5717            // Remove pending intents.  For now we only do this when force
5718            // stopping users, because we have some problems when doing this
5719            // for packages -- app widgets are not currently cleaned up for
5720            // such packages, so they can be left with bad pending intents.
5721            if (mIntentSenderRecords.size() > 0) {
5722                Iterator<WeakReference<PendingIntentRecord>> it
5723                        = mIntentSenderRecords.values().iterator();
5724                while (it.hasNext()) {
5725                    WeakReference<PendingIntentRecord> wpir = it.next();
5726                    if (wpir == null) {
5727                        it.remove();
5728                        continue;
5729                    }
5730                    PendingIntentRecord pir = wpir.get();
5731                    if (pir == null) {
5732                        it.remove();
5733                        continue;
5734                    }
5735                    if (name == null) {
5736                        // Stopping user, remove all objects for the user.
5737                        if (pir.key.userId != userId) {
5738                            // Not the same user, skip it.
5739                            continue;
5740                        }
5741                    } else {
5742                        if (UserHandle.getAppId(pir.uid) != appId) {
5743                            // Different app id, skip it.
5744                            continue;
5745                        }
5746                        if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
5747                            // Different user, skip it.
5748                            continue;
5749                        }
5750                        if (!pir.key.packageName.equals(name)) {
5751                            // Different package, skip it.
5752                            continue;
5753                        }
5754                    }
5755                    if (!doit) {
5756                        return true;
5757                    }
5758                    didSomething = true;
5759                    it.remove();
5760                    pir.canceled = true;
5761                    if (pir.key.activity != null) {
5762                        pir.key.activity.pendingResults.remove(pir.ref);
5763                    }
5764                }
5765            }
5766        }
5767
5768        if (doit) {
5769            if (purgeCache && name != null) {
5770                AttributeCache ac = AttributeCache.instance();
5771                if (ac != null) {
5772                    ac.removePackage(name);
5773                }
5774            }
5775            if (mBooted) {
5776                mStackSupervisor.resumeTopActivitiesLocked();
5777                mStackSupervisor.scheduleIdleLocked();
5778            }
5779        }
5780
5781        return didSomething;
5782    }
5783
5784    private final boolean removeProcessLocked(ProcessRecord app,
5785            boolean callerWillRestart, boolean allowRestart, String reason) {
5786        final String name = app.processName;
5787        final int uid = app.uid;
5788        if (DEBUG_PROCESSES) Slog.d(
5789            TAG, "Force removing proc " + app.toShortString() + " (" + name
5790            + "/" + uid + ")");
5791
5792        mProcessNames.remove(name, uid);
5793        mIsolatedProcesses.remove(app.uid);
5794        if (mHeavyWeightProcess == app) {
5795            mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5796                    mHeavyWeightProcess.userId, 0));
5797            mHeavyWeightProcess = null;
5798        }
5799        boolean needRestart = false;
5800        if (app.pid > 0 && app.pid != MY_PID) {
5801            int pid = app.pid;
5802            synchronized (mPidsSelfLocked) {
5803                mPidsSelfLocked.remove(pid);
5804                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5805            }
5806            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5807            if (app.isolated) {
5808                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5809            }
5810            app.kill(reason, true);
5811            handleAppDiedLocked(app, true, allowRestart);
5812            removeLruProcessLocked(app);
5813
5814            if (app.persistent && !app.isolated) {
5815                if (!callerWillRestart) {
5816                    addAppLocked(app.info, false, null /* ABI override */);
5817                } else {
5818                    needRestart = true;
5819                }
5820            }
5821        } else {
5822            mRemovedProcesses.add(app);
5823        }
5824
5825        return needRestart;
5826    }
5827
5828    private final void processStartTimedOutLocked(ProcessRecord app) {
5829        final int pid = app.pid;
5830        boolean gone = false;
5831        synchronized (mPidsSelfLocked) {
5832            ProcessRecord knownApp = mPidsSelfLocked.get(pid);
5833            if (knownApp != null && knownApp.thread == null) {
5834                mPidsSelfLocked.remove(pid);
5835                gone = true;
5836            }
5837        }
5838
5839        if (gone) {
5840            Slog.w(TAG, "Process " + app + " failed to attach");
5841            EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
5842                    pid, app.uid, app.processName);
5843            mProcessNames.remove(app.processName, app.uid);
5844            mIsolatedProcesses.remove(app.uid);
5845            if (mHeavyWeightProcess == app) {
5846                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
5847                        mHeavyWeightProcess.userId, 0));
5848                mHeavyWeightProcess = null;
5849            }
5850            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
5851            if (app.isolated) {
5852                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
5853            }
5854            // Take care of any launching providers waiting for this process.
5855            checkAppInLaunchingProvidersLocked(app, true);
5856            // Take care of any services that are waiting for the process.
5857            mServices.processStartTimedOutLocked(app);
5858            app.kill("start timeout", true);
5859            if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
5860                Slog.w(TAG, "Unattached app died before backup, skipping");
5861                try {
5862                    IBackupManager bm = IBackupManager.Stub.asInterface(
5863                            ServiceManager.getService(Context.BACKUP_SERVICE));
5864                    bm.agentDisconnected(app.info.packageName);
5865                } catch (RemoteException e) {
5866                    // Can't happen; the backup manager is local
5867                }
5868            }
5869            if (isPendingBroadcastProcessLocked(pid)) {
5870                Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
5871                skipPendingBroadcastLocked(pid);
5872            }
5873        } else {
5874            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
5875        }
5876    }
5877
5878    private final boolean attachApplicationLocked(IApplicationThread thread,
5879            int pid) {
5880
5881        // Find the application record that is being attached...  either via
5882        // the pid if we are running in multiple processes, or just pull the
5883        // next app record if we are emulating process with anonymous threads.
5884        ProcessRecord app;
5885        if (pid != MY_PID && pid >= 0) {
5886            synchronized (mPidsSelfLocked) {
5887                app = mPidsSelfLocked.get(pid);
5888            }
5889        } else {
5890            app = null;
5891        }
5892
5893        if (app == null) {
5894            Slog.w(TAG, "No pending application record for pid " + pid
5895                    + " (IApplicationThread " + thread + "); dropping process");
5896            EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
5897            if (pid > 0 && pid != MY_PID) {
5898                Process.killProcessQuiet(pid);
5899                //TODO: Process.killProcessGroup(app.info.uid, pid);
5900            } else {
5901                try {
5902                    thread.scheduleExit();
5903                } catch (Exception e) {
5904                    // Ignore exceptions.
5905                }
5906            }
5907            return false;
5908        }
5909
5910        // If this application record is still attached to a previous
5911        // process, clean it up now.
5912        if (app.thread != null) {
5913            handleAppDiedLocked(app, true, true);
5914        }
5915
5916        // Tell the process all about itself.
5917
5918        if (localLOGV) Slog.v(
5919                TAG, "Binding process pid " + pid + " to record " + app);
5920
5921        final String processName = app.processName;
5922        try {
5923            AppDeathRecipient adr = new AppDeathRecipient(
5924                    app, pid, thread);
5925            thread.asBinder().linkToDeath(adr, 0);
5926            app.deathRecipient = adr;
5927        } catch (RemoteException e) {
5928            app.resetPackageList(mProcessStats);
5929            startProcessLocked(app, "link fail", processName);
5930            return false;
5931        }
5932
5933        EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
5934
5935        app.makeActive(thread, mProcessStats);
5936        app.curAdj = app.setAdj = -100;
5937        app.curSchedGroup = app.setSchedGroup = Process.THREAD_GROUP_DEFAULT;
5938        app.forcingToForeground = null;
5939        updateProcessForegroundLocked(app, false, false);
5940        app.hasShownUi = false;
5941        app.debugging = false;
5942        app.cached = false;
5943
5944        mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
5945
5946        boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
5947        List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
5948
5949        if (!normalMode) {
5950            Slog.i(TAG, "Launching preboot mode app: " + app);
5951        }
5952
5953        if (localLOGV) Slog.v(
5954            TAG, "New app record " + app
5955            + " thread=" + thread.asBinder() + " pid=" + pid);
5956        try {
5957            int testMode = IApplicationThread.DEBUG_OFF;
5958            if (mDebugApp != null && mDebugApp.equals(processName)) {
5959                testMode = mWaitForDebugger
5960                    ? IApplicationThread.DEBUG_WAIT
5961                    : IApplicationThread.DEBUG_ON;
5962                app.debugging = true;
5963                if (mDebugTransient) {
5964                    mDebugApp = mOrigDebugApp;
5965                    mWaitForDebugger = mOrigWaitForDebugger;
5966                }
5967            }
5968            String profileFile = app.instrumentationProfileFile;
5969            ParcelFileDescriptor profileFd = null;
5970            int samplingInterval = 0;
5971            boolean profileAutoStop = false;
5972            if (mProfileApp != null && mProfileApp.equals(processName)) {
5973                mProfileProc = app;
5974                profileFile = mProfileFile;
5975                profileFd = mProfileFd;
5976                samplingInterval = mSamplingInterval;
5977                profileAutoStop = mAutoStopProfiler;
5978            }
5979            boolean enableOpenGlTrace = false;
5980            if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
5981                enableOpenGlTrace = true;
5982                mOpenGlTraceApp = null;
5983            }
5984
5985            // If the app is being launched for restore or full backup, set it up specially
5986            boolean isRestrictedBackupMode = false;
5987            if (mBackupTarget != null && mBackupAppName.equals(processName)) {
5988                isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
5989                        || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
5990                        || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
5991            }
5992
5993            ensurePackageDexOpt(app.instrumentationInfo != null
5994                    ? app.instrumentationInfo.packageName
5995                    : app.info.packageName);
5996            if (app.instrumentationClass != null) {
5997                ensurePackageDexOpt(app.instrumentationClass.getPackageName());
5998            }
5999            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
6000                    + processName + " with config " + mConfiguration);
6001            ApplicationInfo appInfo = app.instrumentationInfo != null
6002                    ? app.instrumentationInfo : app.info;
6003            app.compat = compatibilityInfoForPackageLocked(appInfo);
6004            if (profileFd != null) {
6005                profileFd = profileFd.dup();
6006            }
6007            ProfilerInfo profilerInfo = profileFile == null ? null
6008                    : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6009            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6010                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6011                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
6012                    isRestrictedBackupMode || !normalMode, app.persistent,
6013                    new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
6014                    mCoreSettingsObserver.getCoreSettingsLocked());
6015            updateLruProcessLocked(app, false, null);
6016            app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6017        } catch (Exception e) {
6018            // todo: Yikes!  What should we do?  For now we will try to
6019            // start another process, but that could easily get us in
6020            // an infinite loop of restarting processes...
6021            Slog.w(TAG, "Exception thrown during bind!", e);
6022
6023            app.resetPackageList(mProcessStats);
6024            app.unlinkDeathRecipient();
6025            startProcessLocked(app, "bind fail", processName);
6026            return false;
6027        }
6028
6029        // Remove this record from the list of starting applications.
6030        mPersistentStartingProcesses.remove(app);
6031        if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
6032                "Attach application locked removing on hold: " + app);
6033        mProcessesOnHold.remove(app);
6034
6035        boolean badApp = false;
6036        boolean didSomething = false;
6037
6038        // See if the top visible activity is waiting to run in this process...
6039        if (normalMode) {
6040            try {
6041                if (mStackSupervisor.attachApplicationLocked(app)) {
6042                    didSomething = true;
6043                }
6044            } catch (Exception e) {
6045                badApp = true;
6046            }
6047        }
6048
6049        // Find any services that should be running in this process...
6050        if (!badApp) {
6051            try {
6052                didSomething |= mServices.attachApplicationLocked(app, processName);
6053            } catch (Exception e) {
6054                badApp = true;
6055            }
6056        }
6057
6058        // Check if a next-broadcast receiver is in this process...
6059        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6060            try {
6061                didSomething |= sendPendingBroadcastsLocked(app);
6062            } catch (Exception e) {
6063                // If the app died trying to launch the receiver we declare it 'bad'
6064                badApp = true;
6065            }
6066        }
6067
6068        // Check whether the next backup agent is in this process...
6069        if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6070            if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
6071            ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
6072            try {
6073                thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6074                        compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6075                        mBackupTarget.backupMode);
6076            } catch (Exception e) {
6077                Slog.w(TAG, "Exception scheduling backup agent creation: ");
6078                e.printStackTrace();
6079            }
6080        }
6081
6082        if (badApp) {
6083            // todo: Also need to kill application to deal with all
6084            // kinds of exceptions.
6085            handleAppDiedLocked(app, false, true);
6086            return false;
6087        }
6088
6089        if (!didSomething) {
6090            updateOomAdjLocked();
6091        }
6092
6093        return true;
6094    }
6095
6096    @Override
6097    public final void attachApplication(IApplicationThread thread) {
6098        synchronized (this) {
6099            int callingPid = Binder.getCallingPid();
6100            final long origId = Binder.clearCallingIdentity();
6101            attachApplicationLocked(thread, callingPid);
6102            Binder.restoreCallingIdentity(origId);
6103        }
6104    }
6105
6106    @Override
6107    public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6108        final long origId = Binder.clearCallingIdentity();
6109        synchronized (this) {
6110            ActivityStack stack = ActivityRecord.getStackLocked(token);
6111            if (stack != null) {
6112                ActivityRecord r =
6113                        mStackSupervisor.activityIdleInternalLocked(token, false, config);
6114                if (stopProfiling) {
6115                    if ((mProfileProc == r.app) && (mProfileFd != null)) {
6116                        try {
6117                            mProfileFd.close();
6118                        } catch (IOException e) {
6119                        }
6120                        clearProfilerLocked();
6121                    }
6122                }
6123            }
6124        }
6125        Binder.restoreCallingIdentity(origId);
6126    }
6127
6128    void postEnableScreenAfterBootLocked() {
6129        mHandler.sendEmptyMessage(ENABLE_SCREEN_AFTER_BOOT_MSG);
6130    }
6131
6132    void enableScreenAfterBoot() {
6133        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6134                SystemClock.uptimeMillis());
6135        mWindowManager.enableScreenAfterBoot();
6136
6137        synchronized (this) {
6138            updateEventDispatchingLocked();
6139        }
6140    }
6141
6142    @Override
6143    public void showBootMessage(final CharSequence msg, final boolean always) {
6144        enforceNotIsolatedCaller("showBootMessage");
6145        mWindowManager.showBootMessage(msg, always);
6146    }
6147
6148    @Override
6149    public void keyguardWaitingForActivityDrawn() {
6150        enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6151        final long token = Binder.clearCallingIdentity();
6152        try {
6153            synchronized (this) {
6154                if (DEBUG_LOCKSCREEN) logLockScreen("");
6155                mWindowManager.keyguardWaitingForActivityDrawn();
6156            }
6157        } finally {
6158            Binder.restoreCallingIdentity(token);
6159        }
6160    }
6161
6162    final void finishBooting() {
6163        // Register receivers to handle package update events
6164        mPackageMonitor.register(mContext, Looper.getMainLooper(), false);
6165
6166        // Let system services know.
6167        mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6168
6169        synchronized (this) {
6170            // Ensure that any processes we had put on hold are now started
6171            // up.
6172            final int NP = mProcessesOnHold.size();
6173            if (NP > 0) {
6174                ArrayList<ProcessRecord> procs =
6175                    new ArrayList<ProcessRecord>(mProcessesOnHold);
6176                for (int ip=0; ip<NP; ip++) {
6177                    if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
6178                            + procs.get(ip));
6179                    startProcessLocked(procs.get(ip), "on-hold", null);
6180                }
6181            }
6182
6183            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6184                // Start looking for apps that are abusing wake locks.
6185                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6186                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6187                // Tell anyone interested that we are done booting!
6188                SystemProperties.set("sys.boot_completed", "1");
6189                SystemProperties.set("dev.bootcomplete", "1");
6190                for (int i=0; i<mStartedUsers.size(); i++) {
6191                    UserStartedState uss = mStartedUsers.valueAt(i);
6192                    if (uss.mState == UserStartedState.STATE_BOOTING) {
6193                        uss.mState = UserStartedState.STATE_RUNNING;
6194                        final int userId = mStartedUsers.keyAt(i);
6195                        Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
6196                        intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
6197                        intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
6198                        broadcastIntentLocked(null, null, intent, null,
6199                                new IIntentReceiver.Stub() {
6200                                    @Override
6201                                    public void performReceive(Intent intent, int resultCode,
6202                                            String data, Bundle extras, boolean ordered,
6203                                            boolean sticky, int sendingUser) {
6204                                        synchronized (ActivityManagerService.this) {
6205                                            requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6206                                                    true, false);
6207                                        }
6208                                    }
6209                                },
6210                                0, null, null,
6211                                android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
6212                                AppOpsManager.OP_NONE, true, false, MY_PID, Process.SYSTEM_UID,
6213                                userId);
6214                    }
6215                }
6216                scheduleStartProfilesLocked();
6217            }
6218        }
6219    }
6220
6221    final void ensureBootCompleted() {
6222        boolean booting;
6223        boolean enableScreen;
6224        synchronized (this) {
6225            booting = mBooting;
6226            mBooting = false;
6227            enableScreen = !mBooted;
6228            mBooted = true;
6229        }
6230
6231        if (booting) {
6232            finishBooting();
6233        }
6234
6235        if (enableScreen) {
6236            enableScreenAfterBoot();
6237        }
6238    }
6239
6240    @Override
6241    public final void activityResumed(IBinder token) {
6242        final long origId = Binder.clearCallingIdentity();
6243        synchronized(this) {
6244            ActivityStack stack = ActivityRecord.getStackLocked(token);
6245            if (stack != null) {
6246                ActivityRecord.activityResumedLocked(token);
6247            }
6248        }
6249        Binder.restoreCallingIdentity(origId);
6250    }
6251
6252    @Override
6253    public final void activityPaused(IBinder token, PersistableBundle persistentState) {
6254        final long origId = Binder.clearCallingIdentity();
6255        synchronized(this) {
6256            ActivityStack stack = ActivityRecord.getStackLocked(token);
6257            if (stack != null) {
6258                stack.activityPausedLocked(token, false, persistentState);
6259            }
6260        }
6261        Binder.restoreCallingIdentity(origId);
6262    }
6263
6264    @Override
6265    public final void activityStopped(IBinder token, Bundle icicle,
6266            PersistableBundle persistentState, CharSequence description) {
6267        if (localLOGV) Slog.v(TAG, "Activity stopped: token=" + token);
6268
6269        // Refuse possible leaked file descriptors
6270        if (icicle != null && icicle.hasFileDescriptors()) {
6271            throw new IllegalArgumentException("File descriptors passed in Bundle");
6272        }
6273
6274        final long origId = Binder.clearCallingIdentity();
6275
6276        synchronized (this) {
6277            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6278            if (r != null) {
6279                r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6280            }
6281        }
6282
6283        trimApplications();
6284
6285        Binder.restoreCallingIdentity(origId);
6286    }
6287
6288    @Override
6289    public final void activityDestroyed(IBinder token) {
6290        if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
6291        synchronized (this) {
6292            ActivityStack stack = ActivityRecord.getStackLocked(token);
6293            if (stack != null) {
6294                stack.activityDestroyedLocked(token);
6295            }
6296        }
6297    }
6298
6299    @Override
6300    public final void backgroundResourcesReleased(IBinder token) {
6301        final long origId = Binder.clearCallingIdentity();
6302        try {
6303            synchronized (this) {
6304                ActivityStack stack = ActivityRecord.getStackLocked(token);
6305                if (stack != null) {
6306                    stack.backgroundResourcesReleased(token);
6307                }
6308            }
6309        } finally {
6310            Binder.restoreCallingIdentity(origId);
6311        }
6312    }
6313
6314    @Override
6315    public final void notifyLaunchTaskBehindComplete(IBinder token) {
6316        mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6317    }
6318
6319    @Override
6320    public final void notifyEnterAnimationComplete(IBinder token) {
6321        mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6322    }
6323
6324    @Override
6325    public String getCallingPackage(IBinder token) {
6326        synchronized (this) {
6327            ActivityRecord r = getCallingRecordLocked(token);
6328            return r != null ? r.info.packageName : null;
6329        }
6330    }
6331
6332    @Override
6333    public ComponentName getCallingActivity(IBinder token) {
6334        synchronized (this) {
6335            ActivityRecord r = getCallingRecordLocked(token);
6336            return r != null ? r.intent.getComponent() : null;
6337        }
6338    }
6339
6340    private ActivityRecord getCallingRecordLocked(IBinder token) {
6341        ActivityRecord r = ActivityRecord.isInStackLocked(token);
6342        if (r == null) {
6343            return null;
6344        }
6345        return r.resultTo;
6346    }
6347
6348    @Override
6349    public ComponentName getActivityClassForToken(IBinder token) {
6350        synchronized(this) {
6351            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6352            if (r == null) {
6353                return null;
6354            }
6355            return r.intent.getComponent();
6356        }
6357    }
6358
6359    @Override
6360    public String getPackageForToken(IBinder token) {
6361        synchronized(this) {
6362            ActivityRecord r = ActivityRecord.isInStackLocked(token);
6363            if (r == null) {
6364                return null;
6365            }
6366            return r.packageName;
6367        }
6368    }
6369
6370    @Override
6371    public IIntentSender getIntentSender(int type,
6372            String packageName, IBinder token, String resultWho,
6373            int requestCode, Intent[] intents, String[] resolvedTypes,
6374            int flags, Bundle options, int userId) {
6375        enforceNotIsolatedCaller("getIntentSender");
6376        // Refuse possible leaked file descriptors
6377        if (intents != null) {
6378            if (intents.length < 1) {
6379                throw new IllegalArgumentException("Intents array length must be >= 1");
6380            }
6381            for (int i=0; i<intents.length; i++) {
6382                Intent intent = intents[i];
6383                if (intent != null) {
6384                    if (intent.hasFileDescriptors()) {
6385                        throw new IllegalArgumentException("File descriptors passed in Intent");
6386                    }
6387                    if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6388                            (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6389                        throw new IllegalArgumentException(
6390                                "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6391                    }
6392                    intents[i] = new Intent(intent);
6393                }
6394            }
6395            if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6396                throw new IllegalArgumentException(
6397                        "Intent array length does not match resolvedTypes length");
6398            }
6399        }
6400        if (options != null) {
6401            if (options.hasFileDescriptors()) {
6402                throw new IllegalArgumentException("File descriptors passed in options");
6403            }
6404        }
6405
6406        synchronized(this) {
6407            int callingUid = Binder.getCallingUid();
6408            int origUserId = userId;
6409            userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6410                    type == ActivityManager.INTENT_SENDER_BROADCAST,
6411                    ALLOW_NON_FULL, "getIntentSender", null);
6412            if (origUserId == UserHandle.USER_CURRENT) {
6413                // We don't want to evaluate this until the pending intent is
6414                // actually executed.  However, we do want to always do the
6415                // security checking for it above.
6416                userId = UserHandle.USER_CURRENT;
6417            }
6418            try {
6419                if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6420                    int uid = AppGlobals.getPackageManager()
6421                            .getPackageUid(packageName, UserHandle.getUserId(callingUid));
6422                    if (!UserHandle.isSameApp(callingUid, uid)) {
6423                        String msg = "Permission Denial: getIntentSender() from pid="
6424                            + Binder.getCallingPid()
6425                            + ", uid=" + Binder.getCallingUid()
6426                            + ", (need uid=" + uid + ")"
6427                            + " is not allowed to send as package " + packageName;
6428                        Slog.w(TAG, msg);
6429                        throw new SecurityException(msg);
6430                    }
6431                }
6432
6433                return getIntentSenderLocked(type, packageName, callingUid, userId,
6434                        token, resultWho, requestCode, intents, resolvedTypes, flags, options);
6435
6436            } catch (RemoteException e) {
6437                throw new SecurityException(e);
6438            }
6439        }
6440    }
6441
6442    IIntentSender getIntentSenderLocked(int type, String packageName,
6443            int callingUid, int userId, IBinder token, String resultWho,
6444            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6445            Bundle options) {
6446        if (DEBUG_MU)
6447            Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6448        ActivityRecord activity = null;
6449        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6450            activity = ActivityRecord.isInStackLocked(token);
6451            if (activity == null) {
6452                return null;
6453            }
6454            if (activity.finishing) {
6455                return null;
6456            }
6457        }
6458
6459        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6460        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6461        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6462        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6463                |PendingIntent.FLAG_UPDATE_CURRENT);
6464
6465        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6466                type, packageName, activity, resultWho,
6467                requestCode, intents, resolvedTypes, flags, options, userId);
6468        WeakReference<PendingIntentRecord> ref;
6469        ref = mIntentSenderRecords.get(key);
6470        PendingIntentRecord rec = ref != null ? ref.get() : null;
6471        if (rec != null) {
6472            if (!cancelCurrent) {
6473                if (updateCurrent) {
6474                    if (rec.key.requestIntent != null) {
6475                        rec.key.requestIntent.replaceExtras(intents != null ?
6476                                intents[intents.length - 1] : null);
6477                    }
6478                    if (intents != null) {
6479                        intents[intents.length-1] = rec.key.requestIntent;
6480                        rec.key.allIntents = intents;
6481                        rec.key.allResolvedTypes = resolvedTypes;
6482                    } else {
6483                        rec.key.allIntents = null;
6484                        rec.key.allResolvedTypes = null;
6485                    }
6486                }
6487                return rec;
6488            }
6489            rec.canceled = true;
6490            mIntentSenderRecords.remove(key);
6491        }
6492        if (noCreate) {
6493            return rec;
6494        }
6495        rec = new PendingIntentRecord(this, key, callingUid);
6496        mIntentSenderRecords.put(key, rec.ref);
6497        if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6498            if (activity.pendingResults == null) {
6499                activity.pendingResults
6500                        = new HashSet<WeakReference<PendingIntentRecord>>();
6501            }
6502            activity.pendingResults.add(rec.ref);
6503        }
6504        return rec;
6505    }
6506
6507    @Override
6508    public void cancelIntentSender(IIntentSender sender) {
6509        if (!(sender instanceof PendingIntentRecord)) {
6510            return;
6511        }
6512        synchronized(this) {
6513            PendingIntentRecord rec = (PendingIntentRecord)sender;
6514            try {
6515                int uid = AppGlobals.getPackageManager()
6516                        .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
6517                if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6518                    String msg = "Permission Denial: cancelIntentSender() from pid="
6519                        + Binder.getCallingPid()
6520                        + ", uid=" + Binder.getCallingUid()
6521                        + " is not allowed to cancel packges "
6522                        + rec.key.packageName;
6523                    Slog.w(TAG, msg);
6524                    throw new SecurityException(msg);
6525                }
6526            } catch (RemoteException e) {
6527                throw new SecurityException(e);
6528            }
6529            cancelIntentSenderLocked(rec, true);
6530        }
6531    }
6532
6533    void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
6534        rec.canceled = true;
6535        mIntentSenderRecords.remove(rec.key);
6536        if (cleanActivity && rec.key.activity != null) {
6537            rec.key.activity.pendingResults.remove(rec.ref);
6538        }
6539    }
6540
6541    @Override
6542    public String getPackageForIntentSender(IIntentSender pendingResult) {
6543        if (!(pendingResult instanceof PendingIntentRecord)) {
6544            return null;
6545        }
6546        try {
6547            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6548            return res.key.packageName;
6549        } catch (ClassCastException e) {
6550        }
6551        return null;
6552    }
6553
6554    @Override
6555    public int getUidForIntentSender(IIntentSender sender) {
6556        if (sender instanceof PendingIntentRecord) {
6557            try {
6558                PendingIntentRecord res = (PendingIntentRecord)sender;
6559                return res.uid;
6560            } catch (ClassCastException e) {
6561            }
6562        }
6563        return -1;
6564    }
6565
6566    @Override
6567    public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
6568        if (!(pendingResult instanceof PendingIntentRecord)) {
6569            return false;
6570        }
6571        try {
6572            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6573            if (res.key.allIntents == null) {
6574                return false;
6575            }
6576            for (int i=0; i<res.key.allIntents.length; i++) {
6577                Intent intent = res.key.allIntents[i];
6578                if (intent.getPackage() != null && intent.getComponent() != null) {
6579                    return false;
6580                }
6581            }
6582            return true;
6583        } catch (ClassCastException e) {
6584        }
6585        return false;
6586    }
6587
6588    @Override
6589    public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
6590        if (!(pendingResult instanceof PendingIntentRecord)) {
6591            return false;
6592        }
6593        try {
6594            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6595            if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
6596                return true;
6597            }
6598            return false;
6599        } catch (ClassCastException e) {
6600        }
6601        return false;
6602    }
6603
6604    @Override
6605    public Intent getIntentForIntentSender(IIntentSender pendingResult) {
6606        if (!(pendingResult instanceof PendingIntentRecord)) {
6607            return null;
6608        }
6609        try {
6610            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6611            return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
6612        } catch (ClassCastException e) {
6613        }
6614        return null;
6615    }
6616
6617    @Override
6618    public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
6619        if (!(pendingResult instanceof PendingIntentRecord)) {
6620            return null;
6621        }
6622        try {
6623            PendingIntentRecord res = (PendingIntentRecord)pendingResult;
6624            Intent intent = res.key.requestIntent;
6625            if (intent != null) {
6626                if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
6627                        || res.lastTagPrefix.equals(prefix))) {
6628                    return res.lastTag;
6629                }
6630                res.lastTagPrefix = prefix;
6631                StringBuilder sb = new StringBuilder(128);
6632                if (prefix != null) {
6633                    sb.append(prefix);
6634                }
6635                if (intent.getAction() != null) {
6636                    sb.append(intent.getAction());
6637                } else if (intent.getComponent() != null) {
6638                    intent.getComponent().appendShortString(sb);
6639                } else {
6640                    sb.append("?");
6641                }
6642                return res.lastTag = sb.toString();
6643            }
6644        } catch (ClassCastException e) {
6645        }
6646        return null;
6647    }
6648
6649    @Override
6650    public void setProcessLimit(int max) {
6651        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6652                "setProcessLimit()");
6653        synchronized (this) {
6654            mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
6655            mProcessLimitOverride = max;
6656        }
6657        trimApplications();
6658    }
6659
6660    @Override
6661    public int getProcessLimit() {
6662        synchronized (this) {
6663            return mProcessLimitOverride;
6664        }
6665    }
6666
6667    void foregroundTokenDied(ForegroundToken token) {
6668        synchronized (ActivityManagerService.this) {
6669            synchronized (mPidsSelfLocked) {
6670                ForegroundToken cur
6671                    = mForegroundProcesses.get(token.pid);
6672                if (cur != token) {
6673                    return;
6674                }
6675                mForegroundProcesses.remove(token.pid);
6676                ProcessRecord pr = mPidsSelfLocked.get(token.pid);
6677                if (pr == null) {
6678                    return;
6679                }
6680                pr.forcingToForeground = null;
6681                updateProcessForegroundLocked(pr, false, false);
6682            }
6683            updateOomAdjLocked();
6684        }
6685    }
6686
6687    @Override
6688    public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
6689        enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
6690                "setProcessForeground()");
6691        synchronized(this) {
6692            boolean changed = false;
6693
6694            synchronized (mPidsSelfLocked) {
6695                ProcessRecord pr = mPidsSelfLocked.get(pid);
6696                if (pr == null && isForeground) {
6697                    Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
6698                    return;
6699                }
6700                ForegroundToken oldToken = mForegroundProcesses.get(pid);
6701                if (oldToken != null) {
6702                    oldToken.token.unlinkToDeath(oldToken, 0);
6703                    mForegroundProcesses.remove(pid);
6704                    if (pr != null) {
6705                        pr.forcingToForeground = null;
6706                    }
6707                    changed = true;
6708                }
6709                if (isForeground && token != null) {
6710                    ForegroundToken newToken = new ForegroundToken() {
6711                        @Override
6712                        public void binderDied() {
6713                            foregroundTokenDied(this);
6714                        }
6715                    };
6716                    newToken.pid = pid;
6717                    newToken.token = token;
6718                    try {
6719                        token.linkToDeath(newToken, 0);
6720                        mForegroundProcesses.put(pid, newToken);
6721                        pr.forcingToForeground = token;
6722                        changed = true;
6723                    } catch (RemoteException e) {
6724                        // If the process died while doing this, we will later
6725                        // do the cleanup with the process death link.
6726                    }
6727                }
6728            }
6729
6730            if (changed) {
6731                updateOomAdjLocked();
6732            }
6733        }
6734    }
6735
6736    // =========================================================
6737    // PERMISSIONS
6738    // =========================================================
6739
6740    static class PermissionController extends IPermissionController.Stub {
6741        ActivityManagerService mActivityManagerService;
6742        PermissionController(ActivityManagerService activityManagerService) {
6743            mActivityManagerService = activityManagerService;
6744        }
6745
6746        @Override
6747        public boolean checkPermission(String permission, int pid, int uid) {
6748            return mActivityManagerService.checkPermission(permission, pid,
6749                    uid) == PackageManager.PERMISSION_GRANTED;
6750        }
6751    }
6752
6753    class IntentFirewallInterface implements IntentFirewall.AMSInterface {
6754        @Override
6755        public int checkComponentPermission(String permission, int pid, int uid,
6756                int owningUid, boolean exported) {
6757            return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
6758                    owningUid, exported);
6759        }
6760
6761        @Override
6762        public Object getAMSLock() {
6763            return ActivityManagerService.this;
6764        }
6765    }
6766
6767    /**
6768     * This can be called with or without the global lock held.
6769     */
6770    int checkComponentPermission(String permission, int pid, int uid,
6771            int owningUid, boolean exported) {
6772        // We might be performing an operation on behalf of an indirect binder
6773        // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
6774        // client identity accordingly before proceeding.
6775        Identity tlsIdentity = sCallerIdentity.get();
6776        if (tlsIdentity != null) {
6777            Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
6778                    + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
6779            uid = tlsIdentity.uid;
6780            pid = tlsIdentity.pid;
6781        }
6782
6783        if (pid == MY_PID) {
6784            return PackageManager.PERMISSION_GRANTED;
6785        }
6786
6787        return ActivityManager.checkComponentPermission(permission, uid,
6788                owningUid, exported);
6789    }
6790
6791    /**
6792     * As the only public entry point for permissions checking, this method
6793     * can enforce the semantic that requesting a check on a null global
6794     * permission is automatically denied.  (Internally a null permission
6795     * string is used when calling {@link #checkComponentPermission} in cases
6796     * when only uid-based security is needed.)
6797     *
6798     * This can be called with or without the global lock held.
6799     */
6800    @Override
6801    public int checkPermission(String permission, int pid, int uid) {
6802        if (permission == null) {
6803            return PackageManager.PERMISSION_DENIED;
6804        }
6805        return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
6806    }
6807
6808    /**
6809     * Binder IPC calls go through the public entry point.
6810     * This can be called with or without the global lock held.
6811     */
6812    int checkCallingPermission(String permission) {
6813        return checkPermission(permission,
6814                Binder.getCallingPid(),
6815                UserHandle.getAppId(Binder.getCallingUid()));
6816    }
6817
6818    /**
6819     * This can be called with or without the global lock held.
6820     */
6821    void enforceCallingPermission(String permission, String func) {
6822        if (checkCallingPermission(permission)
6823                == PackageManager.PERMISSION_GRANTED) {
6824            return;
6825        }
6826
6827        String msg = "Permission Denial: " + func + " from pid="
6828                + Binder.getCallingPid()
6829                + ", uid=" + Binder.getCallingUid()
6830                + " requires " + permission;
6831        Slog.w(TAG, msg);
6832        throw new SecurityException(msg);
6833    }
6834
6835    /**
6836     * Determine if UID is holding permissions required to access {@link Uri} in
6837     * the given {@link ProviderInfo}. Final permission checking is always done
6838     * in {@link ContentProvider}.
6839     */
6840    private final boolean checkHoldingPermissionsLocked(
6841            IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
6842        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
6843                "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
6844        if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
6845            if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
6846                    != PERMISSION_GRANTED) {
6847                return false;
6848            }
6849        }
6850        return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
6851    }
6852
6853    private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
6854            GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
6855        if (pi.applicationInfo.uid == uid) {
6856            return true;
6857        } else if (!pi.exported) {
6858            return false;
6859        }
6860
6861        boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
6862        boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
6863        try {
6864            // check if target holds top-level <provider> permissions
6865            if (!readMet && pi.readPermission != null && considerUidPermissions
6866                    && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
6867                readMet = true;
6868            }
6869            if (!writeMet && pi.writePermission != null && considerUidPermissions
6870                    && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
6871                writeMet = true;
6872            }
6873
6874            // track if unprotected read/write is allowed; any denied
6875            // <path-permission> below removes this ability
6876            boolean allowDefaultRead = pi.readPermission == null;
6877            boolean allowDefaultWrite = pi.writePermission == null;
6878
6879            // check if target holds any <path-permission> that match uri
6880            final PathPermission[] pps = pi.pathPermissions;
6881            if (pps != null) {
6882                final String path = grantUri.uri.getPath();
6883                int i = pps.length;
6884                while (i > 0 && (!readMet || !writeMet)) {
6885                    i--;
6886                    PathPermission pp = pps[i];
6887                    if (pp.match(path)) {
6888                        if (!readMet) {
6889                            final String pprperm = pp.getReadPermission();
6890                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
6891                                    + pprperm + " for " + pp.getPath()
6892                                    + ": match=" + pp.match(path)
6893                                    + " check=" + pm.checkUidPermission(pprperm, uid));
6894                            if (pprperm != null) {
6895                                if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
6896                                        == PERMISSION_GRANTED) {
6897                                    readMet = true;
6898                                } else {
6899                                    allowDefaultRead = false;
6900                                }
6901                            }
6902                        }
6903                        if (!writeMet) {
6904                            final String ppwperm = pp.getWritePermission();
6905                            if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
6906                                    + ppwperm + " for " + pp.getPath()
6907                                    + ": match=" + pp.match(path)
6908                                    + " check=" + pm.checkUidPermission(ppwperm, uid));
6909                            if (ppwperm != null) {
6910                                if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
6911                                        == PERMISSION_GRANTED) {
6912                                    writeMet = true;
6913                                } else {
6914                                    allowDefaultWrite = false;
6915                                }
6916                            }
6917                        }
6918                    }
6919                }
6920            }
6921
6922            // grant unprotected <provider> read/write, if not blocked by
6923            // <path-permission> above
6924            if (allowDefaultRead) readMet = true;
6925            if (allowDefaultWrite) writeMet = true;
6926
6927        } catch (RemoteException e) {
6928            return false;
6929        }
6930
6931        return readMet && writeMet;
6932    }
6933
6934    private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
6935        ProviderInfo pi = null;
6936        ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
6937        if (cpr != null) {
6938            pi = cpr.info;
6939        } else {
6940            try {
6941                pi = AppGlobals.getPackageManager().resolveContentProvider(
6942                        authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
6943            } catch (RemoteException ex) {
6944            }
6945        }
6946        return pi;
6947    }
6948
6949    private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
6950        final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6951        if (targetUris != null) {
6952            return targetUris.get(grantUri);
6953        }
6954        return null;
6955    }
6956
6957    private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
6958            String targetPkg, int targetUid, GrantUri grantUri) {
6959        ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
6960        if (targetUris == null) {
6961            targetUris = Maps.newArrayMap();
6962            mGrantedUriPermissions.put(targetUid, targetUris);
6963        }
6964
6965        UriPermission perm = targetUris.get(grantUri);
6966        if (perm == null) {
6967            perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
6968            targetUris.put(grantUri, perm);
6969        }
6970
6971        return perm;
6972    }
6973
6974    private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
6975            final int modeFlags) {
6976        final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
6977        final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
6978                : UriPermission.STRENGTH_OWNED;
6979
6980        // Root gets to do everything.
6981        if (uid == 0) {
6982            return true;
6983        }
6984
6985        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
6986        if (perms == null) return false;
6987
6988        // First look for exact match
6989        final UriPermission exactPerm = perms.get(grantUri);
6990        if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
6991            return true;
6992        }
6993
6994        // No exact match, look for prefixes
6995        final int N = perms.size();
6996        for (int i = 0; i < N; i++) {
6997            final UriPermission perm = perms.valueAt(i);
6998            if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
6999                    && perm.getStrength(modeFlags) >= minStrength) {
7000                return true;
7001            }
7002        }
7003
7004        return false;
7005    }
7006
7007    /**
7008     * @param uri This uri must NOT contain an embedded userId.
7009     * @param userId The userId in which the uri is to be resolved.
7010     */
7011    @Override
7012    public int checkUriPermission(Uri uri, int pid, int uid,
7013            final int modeFlags, int userId) {
7014        enforceNotIsolatedCaller("checkUriPermission");
7015
7016        // Another redirected-binder-call permissions check as in
7017        // {@link checkComponentPermission}.
7018        Identity tlsIdentity = sCallerIdentity.get();
7019        if (tlsIdentity != null) {
7020            uid = tlsIdentity.uid;
7021            pid = tlsIdentity.pid;
7022        }
7023
7024        // Our own process gets to do everything.
7025        if (pid == MY_PID) {
7026            return PackageManager.PERMISSION_GRANTED;
7027        }
7028        synchronized (this) {
7029            return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7030                    ? PackageManager.PERMISSION_GRANTED
7031                    : PackageManager.PERMISSION_DENIED;
7032        }
7033    }
7034
7035    /**
7036     * Check if the targetPkg can be granted permission to access uri by
7037     * the callingUid using the given modeFlags.  Throws a security exception
7038     * if callingUid is not allowed to do this.  Returns the uid of the target
7039     * if the URI permission grant should be performed; returns -1 if it is not
7040     * needed (for example targetPkg already has permission to access the URI).
7041     * If you already know the uid of the target, you can supply it in
7042     * lastTargetUid else set that to -1.
7043     */
7044    int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7045            final int modeFlags, int lastTargetUid) {
7046        if (!Intent.isAccessUriMode(modeFlags)) {
7047            return -1;
7048        }
7049
7050        if (targetPkg != null) {
7051            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7052                    "Checking grant " + targetPkg + " permission to " + grantUri);
7053        }
7054
7055        final IPackageManager pm = AppGlobals.getPackageManager();
7056
7057        // If this is not a content: uri, we can't do anything with it.
7058        if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7059            if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7060                    "Can't grant URI permission for non-content URI: " + grantUri);
7061            return -1;
7062        }
7063
7064        final String authority = grantUri.uri.getAuthority();
7065        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7066        if (pi == null) {
7067            Slog.w(TAG, "No content provider found for permission check: " +
7068                    grantUri.uri.toSafeString());
7069            return -1;
7070        }
7071
7072        int targetUid = lastTargetUid;
7073        if (targetUid < 0 && targetPkg != null) {
7074            try {
7075                targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
7076                if (targetUid < 0) {
7077                    if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7078                            "Can't grant URI permission no uid for: " + targetPkg);
7079                    return -1;
7080                }
7081            } catch (RemoteException ex) {
7082                return -1;
7083            }
7084        }
7085
7086        if (targetUid >= 0) {
7087            // First...  does the target actually need this permission?
7088            if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7089                // No need to grant the target this permission.
7090                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7091                        "Target " + targetPkg + " already has full permission to " + grantUri);
7092                return -1;
7093            }
7094        } else {
7095            // First...  there is no target package, so can anyone access it?
7096            boolean allowed = pi.exported;
7097            if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7098                if (pi.readPermission != null) {
7099                    allowed = false;
7100                }
7101            }
7102            if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7103                if (pi.writePermission != null) {
7104                    allowed = false;
7105                }
7106            }
7107            if (allowed) {
7108                return -1;
7109            }
7110        }
7111
7112        /* There is a special cross user grant if:
7113         * - The target is on another user.
7114         * - Apps on the current user can access the uri without any uid permissions.
7115         * In this case, we grant a uri permission, even if the ContentProvider does not normally
7116         * grant uri permissions.
7117         */
7118        boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7119                && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7120                modeFlags, false /*without considering the uid permissions*/);
7121
7122        // Second...  is the provider allowing granting of URI permissions?
7123        if (!specialCrossUserGrant) {
7124            if (!pi.grantUriPermissions) {
7125                throw new SecurityException("Provider " + pi.packageName
7126                        + "/" + pi.name
7127                        + " does not allow granting of Uri permissions (uri "
7128                        + grantUri + ")");
7129            }
7130            if (pi.uriPermissionPatterns != null) {
7131                final int N = pi.uriPermissionPatterns.length;
7132                boolean allowed = false;
7133                for (int i=0; i<N; i++) {
7134                    if (pi.uriPermissionPatterns[i] != null
7135                            && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7136                        allowed = true;
7137                        break;
7138                    }
7139                }
7140                if (!allowed) {
7141                    throw new SecurityException("Provider " + pi.packageName
7142                            + "/" + pi.name
7143                            + " does not allow granting of permission to path of Uri "
7144                            + grantUri);
7145                }
7146            }
7147        }
7148
7149        // Third...  does the caller itself have permission to access
7150        // this uri?
7151        if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7152            if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7153                // Require they hold a strong enough Uri permission
7154                if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7155                    throw new SecurityException("Uid " + callingUid
7156                            + " does not have permission to uri " + grantUri);
7157                }
7158            }
7159        }
7160        return targetUid;
7161    }
7162
7163    /**
7164     * @param uri This uri must NOT contain an embedded userId.
7165     * @param userId The userId in which the uri is to be resolved.
7166     */
7167    @Override
7168    public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7169            final int modeFlags, int userId) {
7170        enforceNotIsolatedCaller("checkGrantUriPermission");
7171        synchronized(this) {
7172            return checkGrantUriPermissionLocked(callingUid, targetPkg,
7173                    new GrantUri(userId, uri, false), modeFlags, -1);
7174        }
7175    }
7176
7177    void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7178            final int modeFlags, UriPermissionOwner owner) {
7179        if (!Intent.isAccessUriMode(modeFlags)) {
7180            return;
7181        }
7182
7183        // So here we are: the caller has the assumed permission
7184        // to the uri, and the target doesn't.  Let's now give this to
7185        // the target.
7186
7187        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7188                "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7189
7190        final String authority = grantUri.uri.getAuthority();
7191        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7192        if (pi == null) {
7193            Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7194            return;
7195        }
7196
7197        if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7198            grantUri.prefix = true;
7199        }
7200        final UriPermission perm = findOrCreateUriPermissionLocked(
7201                pi.packageName, targetPkg, targetUid, grantUri);
7202        perm.grantModes(modeFlags, owner);
7203    }
7204
7205    void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7206            final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7207        if (targetPkg == null) {
7208            throw new NullPointerException("targetPkg");
7209        }
7210        int targetUid;
7211        final IPackageManager pm = AppGlobals.getPackageManager();
7212        try {
7213            targetUid = pm.getPackageUid(targetPkg, targetUserId);
7214        } catch (RemoteException ex) {
7215            return;
7216        }
7217
7218        targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7219                targetUid);
7220        if (targetUid < 0) {
7221            return;
7222        }
7223
7224        grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7225                owner);
7226    }
7227
7228    static class NeededUriGrants extends ArrayList<GrantUri> {
7229        final String targetPkg;
7230        final int targetUid;
7231        final int flags;
7232
7233        NeededUriGrants(String targetPkg, int targetUid, int flags) {
7234            this.targetPkg = targetPkg;
7235            this.targetUid = targetUid;
7236            this.flags = flags;
7237        }
7238    }
7239
7240    /**
7241     * Like checkGrantUriPermissionLocked, but takes an Intent.
7242     */
7243    NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7244            String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7245        if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7246                "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7247                + " clip=" + (intent != null ? intent.getClipData() : null)
7248                + " from " + intent + "; flags=0x"
7249                + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7250
7251        if (targetPkg == null) {
7252            throw new NullPointerException("targetPkg");
7253        }
7254
7255        if (intent == null) {
7256            return null;
7257        }
7258        Uri data = intent.getData();
7259        ClipData clip = intent.getClipData();
7260        if (data == null && clip == null) {
7261            return null;
7262        }
7263        // Default userId for uris in the intent (if they don't specify it themselves)
7264        int contentUserHint = intent.getContentUserHint();
7265        if (contentUserHint == UserHandle.USER_CURRENT) {
7266            contentUserHint = UserHandle.getUserId(callingUid);
7267        }
7268        final IPackageManager pm = AppGlobals.getPackageManager();
7269        int targetUid;
7270        if (needed != null) {
7271            targetUid = needed.targetUid;
7272        } else {
7273            try {
7274                targetUid = pm.getPackageUid(targetPkg, targetUserId);
7275            } catch (RemoteException ex) {
7276                return null;
7277            }
7278            if (targetUid < 0) {
7279                if (DEBUG_URI_PERMISSION) {
7280                    Slog.v(TAG, "Can't grant URI permission no uid for: " + targetPkg
7281                            + " on user " + targetUserId);
7282                }
7283                return null;
7284            }
7285        }
7286        if (data != null) {
7287            GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7288            targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7289                    targetUid);
7290            if (targetUid > 0) {
7291                if (needed == null) {
7292                    needed = new NeededUriGrants(targetPkg, targetUid, mode);
7293                }
7294                needed.add(grantUri);
7295            }
7296        }
7297        if (clip != null) {
7298            for (int i=0; i<clip.getItemCount(); i++) {
7299                Uri uri = clip.getItemAt(i).getUri();
7300                if (uri != null) {
7301                    GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7302                    targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7303                            targetUid);
7304                    if (targetUid > 0) {
7305                        if (needed == null) {
7306                            needed = new NeededUriGrants(targetPkg, targetUid, mode);
7307                        }
7308                        needed.add(grantUri);
7309                    }
7310                } else {
7311                    Intent clipIntent = clip.getItemAt(i).getIntent();
7312                    if (clipIntent != null) {
7313                        NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7314                                callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7315                        if (newNeeded != null) {
7316                            needed = newNeeded;
7317                        }
7318                    }
7319                }
7320            }
7321        }
7322
7323        return needed;
7324    }
7325
7326    /**
7327     * Like grantUriPermissionUncheckedLocked, but takes an Intent.
7328     */
7329    void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
7330            UriPermissionOwner owner) {
7331        if (needed != null) {
7332            for (int i=0; i<needed.size(); i++) {
7333                GrantUri grantUri = needed.get(i);
7334                grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
7335                        grantUri, needed.flags, owner);
7336            }
7337        }
7338    }
7339
7340    void grantUriPermissionFromIntentLocked(int callingUid,
7341            String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
7342        NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
7343                intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
7344        if (needed == null) {
7345            return;
7346        }
7347
7348        grantUriPermissionUncheckedFromIntentLocked(needed, owner);
7349    }
7350
7351    /**
7352     * @param uri This uri must NOT contain an embedded userId.
7353     * @param userId The userId in which the uri is to be resolved.
7354     */
7355    @Override
7356    public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
7357            final int modeFlags, int userId) {
7358        enforceNotIsolatedCaller("grantUriPermission");
7359        GrantUri grantUri = new GrantUri(userId, uri, false);
7360        synchronized(this) {
7361            final ProcessRecord r = getRecordForAppLocked(caller);
7362            if (r == null) {
7363                throw new SecurityException("Unable to find app for caller "
7364                        + caller
7365                        + " when granting permission to uri " + grantUri);
7366            }
7367            if (targetPkg == null) {
7368                throw new IllegalArgumentException("null target");
7369            }
7370            if (grantUri == null) {
7371                throw new IllegalArgumentException("null uri");
7372            }
7373
7374            Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
7375                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
7376                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
7377                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
7378
7379            grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
7380                    UserHandle.getUserId(r.uid));
7381        }
7382    }
7383
7384    void removeUriPermissionIfNeededLocked(UriPermission perm) {
7385        if (perm.modeFlags == 0) {
7386            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7387                    perm.targetUid);
7388            if (perms != null) {
7389                if (DEBUG_URI_PERMISSION) Slog.v(TAG,
7390                        "Removing " + perm.targetUid + " permission to " + perm.uri);
7391
7392                perms.remove(perm.uri);
7393                if (perms.isEmpty()) {
7394                    mGrantedUriPermissions.remove(perm.targetUid);
7395                }
7396            }
7397        }
7398    }
7399
7400    private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
7401        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Revoking all granted permissions to " + grantUri);
7402
7403        final IPackageManager pm = AppGlobals.getPackageManager();
7404        final String authority = grantUri.uri.getAuthority();
7405        final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7406        if (pi == null) {
7407            Slog.w(TAG, "No content provider found for permission revoke: "
7408                    + grantUri.toSafeString());
7409            return;
7410        }
7411
7412        // Does the caller have this permission on the URI?
7413        if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7414            // Right now, if you are not the original owner of the permission,
7415            // you are not allowed to revoke it.
7416            //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
7417                throw new SecurityException("Uid " + callingUid
7418                        + " does not have permission to uri " + grantUri);
7419            //}
7420        }
7421
7422        boolean persistChanged = false;
7423
7424        // Go through all of the permissions and remove any that match.
7425        int N = mGrantedUriPermissions.size();
7426        for (int i = 0; i < N; i++) {
7427            final int targetUid = mGrantedUriPermissions.keyAt(i);
7428            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7429
7430            for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7431                final UriPermission perm = it.next();
7432                if (perm.uri.sourceUserId == grantUri.sourceUserId
7433                        && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
7434                    if (DEBUG_URI_PERMISSION)
7435                        Slog.v(TAG,
7436                                "Revoking " + perm.targetUid + " permission to " + perm.uri);
7437                    persistChanged |= perm.revokeModes(
7438                            modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7439                    if (perm.modeFlags == 0) {
7440                        it.remove();
7441                    }
7442                }
7443            }
7444
7445            if (perms.isEmpty()) {
7446                mGrantedUriPermissions.remove(targetUid);
7447                N--;
7448                i--;
7449            }
7450        }
7451
7452        if (persistChanged) {
7453            schedulePersistUriGrants();
7454        }
7455    }
7456
7457    /**
7458     * @param uri This uri must NOT contain an embedded userId.
7459     * @param userId The userId in which the uri is to be resolved.
7460     */
7461    @Override
7462    public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
7463            int userId) {
7464        enforceNotIsolatedCaller("revokeUriPermission");
7465        synchronized(this) {
7466            final ProcessRecord r = getRecordForAppLocked(caller);
7467            if (r == null) {
7468                throw new SecurityException("Unable to find app for caller "
7469                        + caller
7470                        + " when revoking permission to uri " + uri);
7471            }
7472            if (uri == null) {
7473                Slog.w(TAG, "revokeUriPermission: null uri");
7474                return;
7475            }
7476
7477            if (!Intent.isAccessUriMode(modeFlags)) {
7478                return;
7479            }
7480
7481            final IPackageManager pm = AppGlobals.getPackageManager();
7482            final String authority = uri.getAuthority();
7483            final ProviderInfo pi = getProviderInfoLocked(authority, userId);
7484            if (pi == null) {
7485                Slog.w(TAG, "No content provider found for permission revoke: "
7486                        + uri.toSafeString());
7487                return;
7488            }
7489
7490            revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
7491        }
7492    }
7493
7494    /**
7495     * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
7496     * given package.
7497     *
7498     * @param packageName Package name to match, or {@code null} to apply to all
7499     *            packages.
7500     * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
7501     *            to all users.
7502     * @param persistable If persistable grants should be removed.
7503     */
7504    private void removeUriPermissionsForPackageLocked(
7505            String packageName, int userHandle, boolean persistable) {
7506        if (userHandle == UserHandle.USER_ALL && packageName == null) {
7507            throw new IllegalArgumentException("Must narrow by either package or user");
7508        }
7509
7510        boolean persistChanged = false;
7511
7512        int N = mGrantedUriPermissions.size();
7513        for (int i = 0; i < N; i++) {
7514            final int targetUid = mGrantedUriPermissions.keyAt(i);
7515            final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7516
7517            // Only inspect grants matching user
7518            if (userHandle == UserHandle.USER_ALL
7519                    || userHandle == UserHandle.getUserId(targetUid)) {
7520                for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
7521                    final UriPermission perm = it.next();
7522
7523                    // Only inspect grants matching package
7524                    if (packageName == null || perm.sourcePkg.equals(packageName)
7525                            || perm.targetPkg.equals(packageName)) {
7526                        persistChanged |= perm.revokeModes(
7527                                persistable ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
7528
7529                        // Only remove when no modes remain; any persisted grants
7530                        // will keep this alive.
7531                        if (perm.modeFlags == 0) {
7532                            it.remove();
7533                        }
7534                    }
7535                }
7536
7537                if (perms.isEmpty()) {
7538                    mGrantedUriPermissions.remove(targetUid);
7539                    N--;
7540                    i--;
7541                }
7542            }
7543        }
7544
7545        if (persistChanged) {
7546            schedulePersistUriGrants();
7547        }
7548    }
7549
7550    @Override
7551    public IBinder newUriPermissionOwner(String name) {
7552        enforceNotIsolatedCaller("newUriPermissionOwner");
7553        synchronized(this) {
7554            UriPermissionOwner owner = new UriPermissionOwner(this, name);
7555            return owner.getExternalTokenLocked();
7556        }
7557    }
7558
7559    /**
7560     * @param uri This uri must NOT contain an embedded userId.
7561     * @param sourceUserId The userId in which the uri is to be resolved.
7562     * @param targetUserId The userId of the app that receives the grant.
7563     */
7564    @Override
7565    public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
7566            final int modeFlags, int sourceUserId, int targetUserId) {
7567        targetUserId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
7568                targetUserId, false, ALLOW_FULL_ONLY, "grantUriPermissionFromOwner", null);
7569        synchronized(this) {
7570            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7571            if (owner == null) {
7572                throw new IllegalArgumentException("Unknown owner: " + token);
7573            }
7574            if (fromUid != Binder.getCallingUid()) {
7575                if (Binder.getCallingUid() != Process.myUid()) {
7576                    // Only system code can grant URI permissions on behalf
7577                    // of other users.
7578                    throw new SecurityException("nice try");
7579                }
7580            }
7581            if (targetPkg == null) {
7582                throw new IllegalArgumentException("null target");
7583            }
7584            if (uri == null) {
7585                throw new IllegalArgumentException("null uri");
7586            }
7587
7588            grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
7589                    modeFlags, owner, targetUserId);
7590        }
7591    }
7592
7593    /**
7594     * @param uri This uri must NOT contain an embedded userId.
7595     * @param userId The userId in which the uri is to be resolved.
7596     */
7597    @Override
7598    public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
7599        synchronized(this) {
7600            UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
7601            if (owner == null) {
7602                throw new IllegalArgumentException("Unknown owner: " + token);
7603            }
7604
7605            if (uri == null) {
7606                owner.removeUriPermissionsLocked(mode);
7607            } else {
7608                owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
7609            }
7610        }
7611    }
7612
7613    private void schedulePersistUriGrants() {
7614        if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
7615            mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
7616                    10 * DateUtils.SECOND_IN_MILLIS);
7617        }
7618    }
7619
7620    private void writeGrantedUriPermissions() {
7621        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "writeGrantedUriPermissions()");
7622
7623        // Snapshot permissions so we can persist without lock
7624        ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
7625        synchronized (this) {
7626            final int size = mGrantedUriPermissions.size();
7627            for (int i = 0; i < size; i++) {
7628                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
7629                for (UriPermission perm : perms.values()) {
7630                    if (perm.persistedModeFlags != 0) {
7631                        persist.add(perm.snapshot());
7632                    }
7633                }
7634            }
7635        }
7636
7637        FileOutputStream fos = null;
7638        try {
7639            fos = mGrantFile.startWrite();
7640
7641            XmlSerializer out = new FastXmlSerializer();
7642            out.setOutput(fos, "utf-8");
7643            out.startDocument(null, true);
7644            out.startTag(null, TAG_URI_GRANTS);
7645            for (UriPermission.Snapshot perm : persist) {
7646                out.startTag(null, TAG_URI_GRANT);
7647                writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
7648                writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
7649                out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
7650                out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
7651                out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
7652                writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
7653                writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
7654                writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
7655                out.endTag(null, TAG_URI_GRANT);
7656            }
7657            out.endTag(null, TAG_URI_GRANTS);
7658            out.endDocument();
7659
7660            mGrantFile.finishWrite(fos);
7661        } catch (IOException e) {
7662            if (fos != null) {
7663                mGrantFile.failWrite(fos);
7664            }
7665        }
7666    }
7667
7668    private void readGrantedUriPermissionsLocked() {
7669        if (DEBUG_URI_PERMISSION) Slog.v(TAG, "readGrantedUriPermissions()");
7670
7671        final long now = System.currentTimeMillis();
7672
7673        FileInputStream fis = null;
7674        try {
7675            fis = mGrantFile.openRead();
7676            final XmlPullParser in = Xml.newPullParser();
7677            in.setInput(fis, null);
7678
7679            int type;
7680            while ((type = in.next()) != END_DOCUMENT) {
7681                final String tag = in.getName();
7682                if (type == START_TAG) {
7683                    if (TAG_URI_GRANT.equals(tag)) {
7684                        final int sourceUserId;
7685                        final int targetUserId;
7686                        final int userHandle = readIntAttribute(in,
7687                                ATTR_USER_HANDLE, UserHandle.USER_NULL);
7688                        if (userHandle != UserHandle.USER_NULL) {
7689                            // For backwards compatibility.
7690                            sourceUserId = userHandle;
7691                            targetUserId = userHandle;
7692                        } else {
7693                            sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
7694                            targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
7695                        }
7696                        final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
7697                        final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
7698                        final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
7699                        final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
7700                        final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
7701                        final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
7702
7703                        // Sanity check that provider still belongs to source package
7704                        final ProviderInfo pi = getProviderInfoLocked(
7705                                uri.getAuthority(), sourceUserId);
7706                        if (pi != null && sourcePkg.equals(pi.packageName)) {
7707                            int targetUid = -1;
7708                            try {
7709                                targetUid = AppGlobals.getPackageManager()
7710                                        .getPackageUid(targetPkg, targetUserId);
7711                            } catch (RemoteException e) {
7712                            }
7713                            if (targetUid != -1) {
7714                                final UriPermission perm = findOrCreateUriPermissionLocked(
7715                                        sourcePkg, targetPkg, targetUid,
7716                                        new GrantUri(sourceUserId, uri, prefix));
7717                                perm.initPersistedModes(modeFlags, createdTime);
7718                            }
7719                        } else {
7720                            Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
7721                                    + " but instead found " + pi);
7722                        }
7723                    }
7724                }
7725            }
7726        } catch (FileNotFoundException e) {
7727            // Missing grants is okay
7728        } catch (IOException e) {
7729            Log.wtf(TAG, "Failed reading Uri grants", e);
7730        } catch (XmlPullParserException e) {
7731            Log.wtf(TAG, "Failed reading Uri grants", e);
7732        } finally {
7733            IoUtils.closeQuietly(fis);
7734        }
7735    }
7736
7737    /**
7738     * @param uri This uri must NOT contain an embedded userId.
7739     * @param userId The userId in which the uri is to be resolved.
7740     */
7741    @Override
7742    public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7743        enforceNotIsolatedCaller("takePersistableUriPermission");
7744
7745        Preconditions.checkFlagsArgument(modeFlags,
7746                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7747
7748        synchronized (this) {
7749            final int callingUid = Binder.getCallingUid();
7750            boolean persistChanged = false;
7751            GrantUri grantUri = new GrantUri(userId, uri, false);
7752
7753            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7754                    new GrantUri(userId, uri, false));
7755            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7756                    new GrantUri(userId, uri, true));
7757
7758            final boolean exactValid = (exactPerm != null)
7759                    && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
7760            final boolean prefixValid = (prefixPerm != null)
7761                    && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
7762
7763            if (!(exactValid || prefixValid)) {
7764                throw new SecurityException("No persistable permission grants found for UID "
7765                        + callingUid + " and Uri " + grantUri.toSafeString());
7766            }
7767
7768            if (exactValid) {
7769                persistChanged |= exactPerm.takePersistableModes(modeFlags);
7770            }
7771            if (prefixValid) {
7772                persistChanged |= prefixPerm.takePersistableModes(modeFlags);
7773            }
7774
7775            persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
7776
7777            if (persistChanged) {
7778                schedulePersistUriGrants();
7779            }
7780        }
7781    }
7782
7783    /**
7784     * @param uri This uri must NOT contain an embedded userId.
7785     * @param userId The userId in which the uri is to be resolved.
7786     */
7787    @Override
7788    public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
7789        enforceNotIsolatedCaller("releasePersistableUriPermission");
7790
7791        Preconditions.checkFlagsArgument(modeFlags,
7792                Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
7793
7794        synchronized (this) {
7795            final int callingUid = Binder.getCallingUid();
7796            boolean persistChanged = false;
7797
7798            UriPermission exactPerm = findUriPermissionLocked(callingUid,
7799                    new GrantUri(userId, uri, false));
7800            UriPermission prefixPerm = findUriPermissionLocked(callingUid,
7801                    new GrantUri(userId, uri, true));
7802            if (exactPerm == null && prefixPerm == null) {
7803                throw new SecurityException("No permission grants found for UID " + callingUid
7804                        + " and Uri " + uri.toSafeString());
7805            }
7806
7807            if (exactPerm != null) {
7808                persistChanged |= exactPerm.releasePersistableModes(modeFlags);
7809                removeUriPermissionIfNeededLocked(exactPerm);
7810            }
7811            if (prefixPerm != null) {
7812                persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
7813                removeUriPermissionIfNeededLocked(prefixPerm);
7814            }
7815
7816            if (persistChanged) {
7817                schedulePersistUriGrants();
7818            }
7819        }
7820    }
7821
7822    /**
7823     * Prune any older {@link UriPermission} for the given UID until outstanding
7824     * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
7825     *
7826     * @return if any mutations occured that require persisting.
7827     */
7828    private boolean maybePrunePersistedUriGrantsLocked(int uid) {
7829        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7830        if (perms == null) return false;
7831        if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
7832
7833        final ArrayList<UriPermission> persisted = Lists.newArrayList();
7834        for (UriPermission perm : perms.values()) {
7835            if (perm.persistedModeFlags != 0) {
7836                persisted.add(perm);
7837            }
7838        }
7839
7840        final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
7841        if (trimCount <= 0) return false;
7842
7843        Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
7844        for (int i = 0; i < trimCount; i++) {
7845            final UriPermission perm = persisted.get(i);
7846
7847            if (DEBUG_URI_PERMISSION) {
7848                Slog.v(TAG, "Trimming grant created at " + perm.persistedCreateTime);
7849            }
7850
7851            perm.releasePersistableModes(~0);
7852            removeUriPermissionIfNeededLocked(perm);
7853        }
7854
7855        return true;
7856    }
7857
7858    @Override
7859    public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
7860            String packageName, boolean incoming) {
7861        enforceNotIsolatedCaller("getPersistedUriPermissions");
7862        Preconditions.checkNotNull(packageName, "packageName");
7863
7864        final int callingUid = Binder.getCallingUid();
7865        final IPackageManager pm = AppGlobals.getPackageManager();
7866        try {
7867            final int packageUid = pm.getPackageUid(packageName, UserHandle.getUserId(callingUid));
7868            if (packageUid != callingUid) {
7869                throw new SecurityException(
7870                        "Package " + packageName + " does not belong to calling UID " + callingUid);
7871            }
7872        } catch (RemoteException e) {
7873            throw new SecurityException("Failed to verify package name ownership");
7874        }
7875
7876        final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
7877        synchronized (this) {
7878            if (incoming) {
7879                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
7880                        callingUid);
7881                if (perms == null) {
7882                    Slog.w(TAG, "No permission grants found for " + packageName);
7883                } else {
7884                    for (UriPermission perm : perms.values()) {
7885                        if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
7886                            result.add(perm.buildPersistedPublicApiObject());
7887                        }
7888                    }
7889                }
7890            } else {
7891                final int size = mGrantedUriPermissions.size();
7892                for (int i = 0; i < size; i++) {
7893                    final ArrayMap<GrantUri, UriPermission> perms =
7894                            mGrantedUriPermissions.valueAt(i);
7895                    for (UriPermission perm : perms.values()) {
7896                        if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
7897                            result.add(perm.buildPersistedPublicApiObject());
7898                        }
7899                    }
7900                }
7901            }
7902        }
7903        return new ParceledListSlice<android.content.UriPermission>(result);
7904    }
7905
7906    @Override
7907    public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
7908        synchronized (this) {
7909            ProcessRecord app =
7910                who != null ? getRecordForAppLocked(who) : null;
7911            if (app == null) return;
7912
7913            Message msg = Message.obtain();
7914            msg.what = WAIT_FOR_DEBUGGER_MSG;
7915            msg.obj = app;
7916            msg.arg1 = waiting ? 1 : 0;
7917            mHandler.sendMessage(msg);
7918        }
7919    }
7920
7921    @Override
7922    public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
7923        final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
7924        final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
7925        outInfo.availMem = Process.getFreeMemory();
7926        outInfo.totalMem = Process.getTotalMemory();
7927        outInfo.threshold = homeAppMem;
7928        outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
7929        outInfo.hiddenAppThreshold = cachedAppMem;
7930        outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
7931                ProcessList.SERVICE_ADJ);
7932        outInfo.visibleAppThreshold = mProcessList.getMemLevel(
7933                ProcessList.VISIBLE_APP_ADJ);
7934        outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
7935                ProcessList.FOREGROUND_APP_ADJ);
7936    }
7937
7938    // =========================================================
7939    // TASK MANAGEMENT
7940    // =========================================================
7941
7942    @Override
7943    public List<IAppTask> getAppTasks(String callingPackage) {
7944        int callingUid = Binder.getCallingUid();
7945        long ident = Binder.clearCallingIdentity();
7946
7947        synchronized(this) {
7948            ArrayList<IAppTask> list = new ArrayList<IAppTask>();
7949            try {
7950                if (localLOGV) Slog.v(TAG, "getAppTasks");
7951
7952                final int N = mRecentTasks.size();
7953                for (int i = 0; i < N; i++) {
7954                    TaskRecord tr = mRecentTasks.get(i);
7955                    // Skip tasks that do not match the caller.  We don't need to verify
7956                    // callingPackage, because we are also limiting to callingUid and know
7957                    // that will limit to the correct security sandbox.
7958                    if (tr.effectiveUid != callingUid) {
7959                        continue;
7960                    }
7961                    Intent intent = tr.getBaseIntent();
7962                    if (intent == null ||
7963                            !callingPackage.equals(intent.getComponent().getPackageName())) {
7964                        continue;
7965                    }
7966                    ActivityManager.RecentTaskInfo taskInfo =
7967                            createRecentTaskInfoFromTaskRecord(tr);
7968                    AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
7969                    list.add(taskImpl);
7970                }
7971            } finally {
7972                Binder.restoreCallingIdentity(ident);
7973            }
7974            return list;
7975        }
7976    }
7977
7978    @Override
7979    public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
7980        final int callingUid = Binder.getCallingUid();
7981        ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
7982
7983        synchronized(this) {
7984            if (localLOGV) Slog.v(
7985                TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
7986
7987            final boolean allowed = checkCallingPermission(
7988                    android.Manifest.permission.GET_TASKS)
7989                    == PackageManager.PERMISSION_GRANTED;
7990            if (!allowed) {
7991                Slog.w(TAG, "getTasks: caller " + callingUid
7992                        + " does not hold GET_TASKS; limiting output");
7993            }
7994
7995            // TODO: Improve with MRU list from all ActivityStacks.
7996            mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
7997        }
7998
7999        return list;
8000    }
8001
8002    TaskRecord getMostRecentTask() {
8003        return mRecentTasks.get(0);
8004    }
8005
8006    /**
8007     * Creates a new RecentTaskInfo from a TaskRecord.
8008     */
8009    private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8010        // Update the task description to reflect any changes in the task stack
8011        tr.updateTaskDescription();
8012
8013        // Compose the recent task info
8014        ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8015        rti.id = tr.getTopActivity() == null ? -1 : tr.taskId;
8016        rti.persistentId = tr.taskId;
8017        rti.baseIntent = new Intent(tr.getBaseIntent());
8018        rti.origActivity = tr.origActivity;
8019        rti.description = tr.lastDescription;
8020        rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8021        rti.userId = tr.userId;
8022        rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8023        rti.firstActiveTime = tr.firstActiveTime;
8024        rti.lastActiveTime = tr.lastActiveTime;
8025        rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8026        rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8027        return rti;
8028    }
8029
8030    @Override
8031    public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8032        final int callingUid = Binder.getCallingUid();
8033        userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8034                false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8035
8036        final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8037        final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8038        synchronized (this) {
8039            final boolean allowed = checkCallingPermission(android.Manifest.permission.GET_TASKS)
8040                    == PackageManager.PERMISSION_GRANTED;
8041            if (!allowed) {
8042                Slog.w(TAG, "getRecentTasks: caller " + callingUid
8043                        + " does not hold GET_TASKS; limiting output");
8044            }
8045            final boolean detailed = checkCallingPermission(
8046                    android.Manifest.permission.GET_DETAILED_TASKS)
8047                    == PackageManager.PERMISSION_GRANTED;
8048
8049            final int N = mRecentTasks.size();
8050            ArrayList<ActivityManager.RecentTaskInfo> res
8051                    = new ArrayList<ActivityManager.RecentTaskInfo>(
8052                            maxNum < N ? maxNum : N);
8053
8054            final Set<Integer> includedUsers;
8055            if (includeProfiles) {
8056                includedUsers = getProfileIdsLocked(userId);
8057            } else {
8058                includedUsers = new HashSet<Integer>();
8059            }
8060            includedUsers.add(Integer.valueOf(userId));
8061
8062            for (int i=0; i<N && maxNum > 0; i++) {
8063                TaskRecord tr = mRecentTasks.get(i);
8064                // Only add calling user or related users recent tasks
8065                if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8066                    if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not user: " + tr);
8067                    continue;
8068                }
8069
8070                // Return the entry if desired by the caller.  We always return
8071                // the first entry, because callers always expect this to be the
8072                // foreground app.  We may filter others if the caller has
8073                // not supplied RECENT_WITH_EXCLUDED and there is some reason
8074                // we should exclude the entry.
8075
8076                if (i == 0
8077                        || withExcluded
8078                        || (tr.intent == null)
8079                        || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8080                                == 0)) {
8081                    if (!allowed) {
8082                        // If the caller doesn't have the GET_TASKS permission, then only
8083                        // allow them to see a small subset of tasks -- their own and home.
8084                        if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8085                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, not allowed: " + tr);
8086                            continue;
8087                        }
8088                    }
8089                    if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8090                        if (tr.stack != null && tr.stack.isHomeStack()) {
8091                            if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, home stack task: " + tr);
8092                            continue;
8093                        }
8094                    }
8095                    if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8096                        // Don't include auto remove tasks that are finished or finishing.
8097                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, auto-remove without activity: "
8098                                + tr);
8099                        continue;
8100                    }
8101                    if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8102                            && !tr.isAvailable) {
8103                        if (DEBUG_RECENTS) Slog.d(TAG, "Skipping, unavail real act: " + tr);
8104                        continue;
8105                    }
8106
8107                    ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8108                    if (!detailed) {
8109                        rti.baseIntent.replaceExtras((Bundle)null);
8110                    }
8111
8112                    res.add(rti);
8113                    maxNum--;
8114                }
8115            }
8116            return res;
8117        }
8118    }
8119
8120    private TaskRecord recentTaskForIdLocked(int id) {
8121        final int N = mRecentTasks.size();
8122            for (int i=0; i<N; i++) {
8123                TaskRecord tr = mRecentTasks.get(i);
8124                if (tr.taskId == id) {
8125                    return tr;
8126                }
8127            }
8128            return null;
8129    }
8130
8131    @Override
8132    public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8133        synchronized (this) {
8134            enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8135                    "getTaskThumbnail()");
8136            TaskRecord tr = recentTaskForIdLocked(id);
8137            if (tr != null) {
8138                return tr.getTaskThumbnailLocked();
8139            }
8140        }
8141        return null;
8142    }
8143
8144    @Override
8145    public int addAppTask(IBinder activityToken, Intent intent,
8146            ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8147        final int callingUid = Binder.getCallingUid();
8148        final long callingIdent = Binder.clearCallingIdentity();
8149
8150        try {
8151            synchronized (this) {
8152                ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8153                if (r == null) {
8154                    throw new IllegalArgumentException("Activity does not exist; token="
8155                            + activityToken);
8156                }
8157                ComponentName comp = intent.getComponent();
8158                if (comp == null) {
8159                    throw new IllegalArgumentException("Intent " + intent
8160                            + " must specify explicit component");
8161                }
8162                if (thumbnail.getWidth() != mThumbnailWidth
8163                        || thumbnail.getHeight() != mThumbnailHeight) {
8164                    throw new IllegalArgumentException("Bad thumbnail size: got "
8165                            + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8166                            + mThumbnailWidth + "x" + mThumbnailHeight);
8167                }
8168                if (intent.getSelector() != null) {
8169                    intent.setSelector(null);
8170                }
8171                if (intent.getSourceBounds() != null) {
8172                    intent.setSourceBounds(null);
8173                }
8174                if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8175                    if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8176                        // The caller has added this as an auto-remove task...  that makes no
8177                        // sense, so turn off auto-remove.
8178                        intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8179                    }
8180                } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8181                    // Must be a new task.
8182                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8183                }
8184                if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8185                    mLastAddedTaskActivity = null;
8186                }
8187                ActivityInfo ainfo = mLastAddedTaskActivity;
8188                if (ainfo == null) {
8189                    ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8190                            comp, 0, UserHandle.getUserId(callingUid));
8191                    if (ainfo.applicationInfo.uid != callingUid) {
8192                        throw new SecurityException(
8193                                "Can't add task for another application: target uid="
8194                                + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
8195                    }
8196                }
8197
8198                TaskRecord task = new TaskRecord(this, mStackSupervisor.getNextTaskId(), ainfo,
8199                        intent, description);
8200
8201                int trimIdx = trimRecentsForTask(task, false);
8202                if (trimIdx >= 0) {
8203                    // If this would have caused a trim, then we'll abort because that
8204                    // means it would be added at the end of the list but then just removed.
8205                    return -1;
8206                }
8207
8208                final int N = mRecentTasks.size();
8209                if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
8210                    final TaskRecord tr = mRecentTasks.remove(N - 1);
8211                    tr.removedFromRecents(mTaskPersister);
8212                }
8213
8214                task.inRecents = true;
8215                mRecentTasks.add(task);
8216                r.task.stack.addTask(task, false, false);
8217
8218                task.setLastThumbnail(thumbnail);
8219                task.freeLastThumbnail();
8220
8221                return task.taskId;
8222            }
8223        } finally {
8224            Binder.restoreCallingIdentity(callingIdent);
8225        }
8226    }
8227
8228    @Override
8229    public Point getAppTaskThumbnailSize() {
8230        synchronized (this) {
8231            return new Point(mThumbnailWidth,  mThumbnailHeight);
8232        }
8233    }
8234
8235    @Override
8236    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
8237        synchronized (this) {
8238            ActivityRecord r = ActivityRecord.isInStackLocked(token);
8239            if (r != null) {
8240                r.taskDescription = td;
8241                r.task.updateTaskDescription();
8242            }
8243        }
8244    }
8245
8246    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
8247        mRecentTasks.remove(tr);
8248        tr.removedFromRecents(mTaskPersister);
8249        final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
8250        Intent baseIntent = new Intent(
8251                tr.intent != null ? tr.intent : tr.affinityIntent);
8252        ComponentName component = baseIntent.getComponent();
8253        if (component == null) {
8254            Slog.w(TAG, "Now component for base intent of task: " + tr);
8255            return;
8256        }
8257
8258        // Find any running services associated with this app.
8259        mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
8260
8261        if (killProcesses) {
8262            // Find any running processes associated with this app.
8263            final String pkg = component.getPackageName();
8264            ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
8265            ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
8266            for (int i=0; i<pmap.size(); i++) {
8267                SparseArray<ProcessRecord> uids = pmap.valueAt(i);
8268                for (int j=0; j<uids.size(); j++) {
8269                    ProcessRecord proc = uids.valueAt(j);
8270                    if (proc.userId != tr.userId) {
8271                        continue;
8272                    }
8273                    if (!proc.pkgList.containsKey(pkg)) {
8274                        continue;
8275                    }
8276                    procs.add(proc);
8277                }
8278            }
8279
8280            // Kill the running processes.
8281            for (int i=0; i<procs.size(); i++) {
8282                ProcessRecord pr = procs.get(i);
8283                if (pr == mHomeProcess) {
8284                    // Don't kill the home process along with tasks from the same package.
8285                    continue;
8286                }
8287                if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
8288                    pr.kill("remove task", true);
8289                } else {
8290                    pr.waitingToKill = "remove task";
8291                }
8292            }
8293        }
8294    }
8295
8296    /**
8297     * Removes the task with the specified task id.
8298     *
8299     * @param taskId Identifier of the task to be removed.
8300     * @param flags Additional operational flags.  May be 0 or
8301     * {@link ActivityManager#REMOVE_TASK_KILL_PROCESS}.
8302     * @return Returns true if the given task was found and removed.
8303     */
8304    private boolean removeTaskByIdLocked(int taskId, int flags) {
8305        TaskRecord tr = recentTaskForIdLocked(taskId);
8306        if (tr != null) {
8307            tr.removeTaskActivitiesLocked();
8308            cleanUpRemovedTaskLocked(tr, flags);
8309            if (tr.isPersistable) {
8310                notifyTaskPersisterLocked(null, true);
8311            }
8312            return true;
8313        }
8314        return false;
8315    }
8316
8317    @Override
8318    public boolean removeTask(int taskId, int flags) {
8319        synchronized (this) {
8320            enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
8321                    "removeTask()");
8322            long ident = Binder.clearCallingIdentity();
8323            try {
8324                return removeTaskByIdLocked(taskId, flags);
8325            } finally {
8326                Binder.restoreCallingIdentity(ident);
8327            }
8328        }
8329    }
8330
8331    /**
8332     * TODO: Add mController hook
8333     */
8334    @Override
8335    public void moveTaskToFront(int taskId, int flags, Bundle options) {
8336        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8337                "moveTaskToFront()");
8338
8339        if (DEBUG_STACK) Slog.d(TAG, "moveTaskToFront: moving taskId=" + taskId);
8340        synchronized(this) {
8341            moveTaskToFrontLocked(taskId, flags, options);
8342        }
8343    }
8344
8345    void moveTaskToFrontLocked(int taskId, int flags, Bundle options) {
8346        if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8347                Binder.getCallingUid(), "Task to front")) {
8348            ActivityOptions.abort(options);
8349            return;
8350        }
8351        final long origId = Binder.clearCallingIdentity();
8352        try {
8353            final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
8354            if (task == null) {
8355                return;
8356            }
8357            if (mStackSupervisor.isLockTaskModeViolation(task)) {
8358                mStackSupervisor.showLockTaskToast();
8359                Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
8360                return;
8361            }
8362            final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
8363            if (prev != null && prev.isRecentsActivity()) {
8364                task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
8365            }
8366            mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options);
8367        } finally {
8368            Binder.restoreCallingIdentity(origId);
8369        }
8370        ActivityOptions.abort(options);
8371    }
8372
8373    @Override
8374    public void moveTaskToBack(int taskId) {
8375        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8376                "moveTaskToBack()");
8377
8378        synchronized(this) {
8379            TaskRecord tr = recentTaskForIdLocked(taskId);
8380            if (tr != null) {
8381                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToBack: moving task=" + tr);
8382                ActivityStack stack = tr.stack;
8383                if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
8384                    if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8385                            Binder.getCallingUid(), "Task to back")) {
8386                        return;
8387                    }
8388                }
8389                final long origId = Binder.clearCallingIdentity();
8390                try {
8391                    stack.moveTaskToBackLocked(taskId, null);
8392                } finally {
8393                    Binder.restoreCallingIdentity(origId);
8394                }
8395            }
8396        }
8397    }
8398
8399    /**
8400     * Moves an activity, and all of the other activities within the same task, to the bottom
8401     * of the history stack.  The activity's order within the task is unchanged.
8402     *
8403     * @param token A reference to the activity we wish to move
8404     * @param nonRoot If false then this only works if the activity is the root
8405     *                of a task; if true it will work for any activity in a task.
8406     * @return Returns true if the move completed, false if not.
8407     */
8408    @Override
8409    public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
8410        enforceNotIsolatedCaller("moveActivityTaskToBack");
8411        synchronized(this) {
8412            final long origId = Binder.clearCallingIdentity();
8413            int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
8414            if (taskId >= 0) {
8415                return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
8416            }
8417            Binder.restoreCallingIdentity(origId);
8418        }
8419        return false;
8420    }
8421
8422    @Override
8423    public void moveTaskBackwards(int task) {
8424        enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
8425                "moveTaskBackwards()");
8426
8427        synchronized(this) {
8428            if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
8429                    Binder.getCallingUid(), "Task backwards")) {
8430                return;
8431            }
8432            final long origId = Binder.clearCallingIdentity();
8433            moveTaskBackwardsLocked(task);
8434            Binder.restoreCallingIdentity(origId);
8435        }
8436    }
8437
8438    private final void moveTaskBackwardsLocked(int task) {
8439        Slog.e(TAG, "moveTaskBackwards not yet implemented!");
8440    }
8441
8442    @Override
8443    public IBinder getHomeActivityToken() throws RemoteException {
8444        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8445                "getHomeActivityToken()");
8446        synchronized (this) {
8447            return mStackSupervisor.getHomeActivityToken();
8448        }
8449    }
8450
8451    @Override
8452    public IActivityContainer createActivityContainer(IBinder parentActivityToken,
8453            IActivityContainerCallback callback) throws RemoteException {
8454        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8455                "createActivityContainer()");
8456        synchronized (this) {
8457            if (parentActivityToken == null) {
8458                throw new IllegalArgumentException("parent token must not be null");
8459            }
8460            ActivityRecord r = ActivityRecord.forToken(parentActivityToken);
8461            if (r == null) {
8462                return null;
8463            }
8464            if (callback == null) {
8465                throw new IllegalArgumentException("callback must not be null");
8466            }
8467            return mStackSupervisor.createActivityContainer(r, callback);
8468        }
8469    }
8470
8471    @Override
8472    public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
8473        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8474                "deleteActivityContainer()");
8475        synchronized (this) {
8476            mStackSupervisor.deleteActivityContainer(container);
8477        }
8478    }
8479
8480    @Override
8481    public IActivityContainer getEnclosingActivityContainer(IBinder activityToken)
8482            throws RemoteException {
8483        synchronized (this) {
8484            ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
8485            if (stack != null) {
8486                return stack.mActivityContainer;
8487            }
8488            return null;
8489        }
8490    }
8491
8492    @Override
8493    public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
8494        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8495                "moveTaskToStack()");
8496        if (stackId == HOME_STACK_ID) {
8497            Slog.e(TAG, "moveTaskToStack: Attempt to move task " + taskId + " to home stack",
8498                    new RuntimeException("here").fillInStackTrace());
8499        }
8500        synchronized (this) {
8501            long ident = Binder.clearCallingIdentity();
8502            try {
8503                if (DEBUG_STACK) Slog.d(TAG, "moveTaskToStack: moving task=" + taskId + " to stackId="
8504                        + stackId + " toTop=" + toTop);
8505                mStackSupervisor.moveTaskToStack(taskId, stackId, toTop);
8506            } finally {
8507                Binder.restoreCallingIdentity(ident);
8508            }
8509        }
8510    }
8511
8512    @Override
8513    public void resizeStack(int stackBoxId, Rect bounds) {
8514        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8515                "resizeStackBox()");
8516        long ident = Binder.clearCallingIdentity();
8517        try {
8518            mWindowManager.resizeStack(stackBoxId, bounds);
8519        } finally {
8520            Binder.restoreCallingIdentity(ident);
8521        }
8522    }
8523
8524    @Override
8525    public List<StackInfo> getAllStackInfos() {
8526        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8527                "getAllStackInfos()");
8528        long ident = Binder.clearCallingIdentity();
8529        try {
8530            synchronized (this) {
8531                return mStackSupervisor.getAllStackInfosLocked();
8532            }
8533        } finally {
8534            Binder.restoreCallingIdentity(ident);
8535        }
8536    }
8537
8538    @Override
8539    public StackInfo getStackInfo(int stackId) {
8540        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8541                "getStackInfo()");
8542        long ident = Binder.clearCallingIdentity();
8543        try {
8544            synchronized (this) {
8545                return mStackSupervisor.getStackInfoLocked(stackId);
8546            }
8547        } finally {
8548            Binder.restoreCallingIdentity(ident);
8549        }
8550    }
8551
8552    @Override
8553    public boolean isInHomeStack(int taskId) {
8554        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8555                "getStackInfo()");
8556        long ident = Binder.clearCallingIdentity();
8557        try {
8558            synchronized (this) {
8559                TaskRecord tr = recentTaskForIdLocked(taskId);
8560                return tr != null && tr.stack != null && tr.stack.isHomeStack();
8561            }
8562        } finally {
8563            Binder.restoreCallingIdentity(ident);
8564        }
8565    }
8566
8567    @Override
8568    public int getTaskForActivity(IBinder token, boolean onlyRoot) {
8569        synchronized(this) {
8570            return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
8571        }
8572    }
8573
8574    private boolean isLockTaskAuthorized(String pkg) {
8575        final DevicePolicyManager dpm = (DevicePolicyManager)
8576                mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
8577        try {
8578            int uid = mContext.getPackageManager().getPackageUid(pkg,
8579                    Binder.getCallingUserHandle().getIdentifier());
8580            return (uid == Binder.getCallingUid()) && dpm != null && dpm.isLockTaskPermitted(pkg);
8581        } catch (NameNotFoundException e) {
8582            return false;
8583        }
8584    }
8585
8586    void startLockTaskMode(TaskRecord task) {
8587        final String pkg;
8588        synchronized (this) {
8589            pkg = task.intent.getComponent().getPackageName();
8590        }
8591        boolean isSystemInitiated = Binder.getCallingUid() == Process.SYSTEM_UID;
8592        if (!isSystemInitiated && !isLockTaskAuthorized(pkg)) {
8593            final TaskRecord taskRecord = task;
8594            mHandler.post(new Runnable() {
8595                @Override
8596                public void run() {
8597                    mLockToAppRequest.showLockTaskPrompt(taskRecord);
8598                }
8599            });
8600            return;
8601        }
8602        long ident = Binder.clearCallingIdentity();
8603        try {
8604            synchronized (this) {
8605                // Since we lost lock on task, make sure it is still there.
8606                task = mStackSupervisor.anyTaskForIdLocked(task.taskId);
8607                if (task != null) {
8608                    if (!isSystemInitiated
8609                            && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) {
8610                        throw new IllegalArgumentException("Invalid task, not in foreground");
8611                    }
8612                    mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated);
8613                }
8614            }
8615        } finally {
8616            Binder.restoreCallingIdentity(ident);
8617        }
8618    }
8619
8620    @Override
8621    public void startLockTaskMode(int taskId) {
8622        final TaskRecord task;
8623        long ident = Binder.clearCallingIdentity();
8624        try {
8625            synchronized (this) {
8626                task = mStackSupervisor.anyTaskForIdLocked(taskId);
8627            }
8628        } finally {
8629            Binder.restoreCallingIdentity(ident);
8630        }
8631        if (task != null) {
8632            startLockTaskMode(task);
8633        }
8634    }
8635
8636    @Override
8637    public void startLockTaskMode(IBinder token) {
8638        final TaskRecord task;
8639        long ident = Binder.clearCallingIdentity();
8640        try {
8641            synchronized (this) {
8642                final ActivityRecord r = ActivityRecord.forToken(token);
8643                if (r == null) {
8644                    return;
8645                }
8646                task = r.task;
8647            }
8648        } finally {
8649            Binder.restoreCallingIdentity(ident);
8650        }
8651        if (task != null) {
8652            startLockTaskMode(task);
8653        }
8654    }
8655
8656    @Override
8657    public void startLockTaskModeOnCurrent() throws RemoteException {
8658        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8659                "startLockTaskModeOnCurrent");
8660        ActivityRecord r = null;
8661        synchronized (this) {
8662            r = mStackSupervisor.topRunningActivityLocked();
8663        }
8664        startLockTaskMode(r.task);
8665    }
8666
8667    @Override
8668    public void stopLockTaskMode() {
8669        // Verify that the user matches the package of the intent for the TaskRecord
8670        // we are locked to or systtem.  This will ensure the same caller for startLockTaskMode
8671        // and stopLockTaskMode.
8672        final int callingUid = Binder.getCallingUid();
8673        if (callingUid != Process.SYSTEM_UID) {
8674            try {
8675                String pkg =
8676                        mStackSupervisor.mLockTaskModeTask.intent.getComponent().getPackageName();
8677                int uid = mContext.getPackageManager().getPackageUid(pkg,
8678                        Binder.getCallingUserHandle().getIdentifier());
8679                if (uid != callingUid) {
8680                    throw new SecurityException("Invalid uid, expected " + uid);
8681                }
8682            } catch (NameNotFoundException e) {
8683                Log.d(TAG, "stopLockTaskMode " + e);
8684                return;
8685            }
8686        }
8687        long ident = Binder.clearCallingIdentity();
8688        try {
8689            Log.d(TAG, "stopLockTaskMode");
8690            // Stop lock task
8691            synchronized (this) {
8692                mStackSupervisor.setLockTaskModeLocked(null, false);
8693            }
8694        } finally {
8695            Binder.restoreCallingIdentity(ident);
8696        }
8697    }
8698
8699    @Override
8700    public void stopLockTaskModeOnCurrent() throws RemoteException {
8701        enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
8702                "stopLockTaskModeOnCurrent");
8703        long ident = Binder.clearCallingIdentity();
8704        try {
8705            stopLockTaskMode();
8706        } finally {
8707            Binder.restoreCallingIdentity(ident);
8708        }
8709    }
8710
8711    @Override
8712    public boolean isInLockTaskMode() {
8713        synchronized (this) {
8714            return mStackSupervisor.isInLockTaskMode();
8715        }
8716    }
8717
8718    // =========================================================
8719    // CONTENT PROVIDERS
8720    // =========================================================
8721
8722    private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
8723        List<ProviderInfo> providers = null;
8724        try {
8725            providers = AppGlobals.getPackageManager().
8726                queryContentProviders(app.processName, app.uid,
8727                        STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
8728        } catch (RemoteException ex) {
8729        }
8730        if (DEBUG_MU)
8731            Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
8732        int userId = app.userId;
8733        if (providers != null) {
8734            int N = providers.size();
8735            app.pubProviders.ensureCapacity(N + app.pubProviders.size());
8736            for (int i=0; i<N; i++) {
8737                ProviderInfo cpi =
8738                    (ProviderInfo)providers.get(i);
8739                boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
8740                        cpi.name, cpi.flags);
8741                if (singleton && UserHandle.getUserId(app.uid) != 0) {
8742                    // This is a singleton provider, but a user besides the
8743                    // default user is asking to initialize a process it runs
8744                    // in...  well, no, it doesn't actually run in this process,
8745                    // it runs in the process of the default user.  Get rid of it.
8746                    providers.remove(i);
8747                    N--;
8748                    i--;
8749                    continue;
8750                }
8751
8752                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
8753                ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
8754                if (cpr == null) {
8755                    cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
8756                    mProviderMap.putProviderByClass(comp, cpr);
8757                }
8758                if (DEBUG_MU)
8759                    Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
8760                app.pubProviders.put(cpi.name, cpr);
8761                if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
8762                    // Don't add this if it is a platform component that is marked
8763                    // to run in multiple processes, because this is actually
8764                    // part of the framework so doesn't make sense to track as a
8765                    // separate apk in the process.
8766                    app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
8767                            mProcessStats);
8768                }
8769                ensurePackageDexOpt(cpi.applicationInfo.packageName);
8770            }
8771        }
8772        return providers;
8773    }
8774
8775    /**
8776     * Check if {@link ProcessRecord} has a possible chance at accessing the
8777     * given {@link ProviderInfo}. Final permission checking is always done
8778     * in {@link ContentProvider}.
8779     */
8780    private final String checkContentProviderPermissionLocked(
8781            ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
8782        final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
8783        final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
8784        boolean checkedGrants = false;
8785        if (checkUser) {
8786            // Looking for cross-user grants before enforcing the typical cross-users permissions
8787            int tmpTargetUserId = unsafeConvertIncomingUser(userId);
8788            if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
8789                if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
8790                    return null;
8791                }
8792                checkedGrants = true;
8793            }
8794            userId = handleIncomingUser(callingPid, callingUid, userId,
8795                    false, ALLOW_NON_FULL,
8796                    "checkContentProviderPermissionLocked " + cpi.authority, null);
8797            if (userId != tmpTargetUserId) {
8798                // When we actually went to determine the final targer user ID, this ended
8799                // up different than our initial check for the authority.  This is because
8800                // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
8801                // SELF.  So we need to re-check the grants again.
8802                checkedGrants = false;
8803            }
8804        }
8805        if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
8806                cpi.applicationInfo.uid, cpi.exported)
8807                == PackageManager.PERMISSION_GRANTED) {
8808            return null;
8809        }
8810        if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
8811                cpi.applicationInfo.uid, cpi.exported)
8812                == PackageManager.PERMISSION_GRANTED) {
8813            return null;
8814        }
8815
8816        PathPermission[] pps = cpi.pathPermissions;
8817        if (pps != null) {
8818            int i = pps.length;
8819            while (i > 0) {
8820                i--;
8821                PathPermission pp = pps[i];
8822                String pprperm = pp.getReadPermission();
8823                if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
8824                        cpi.applicationInfo.uid, cpi.exported)
8825                        == PackageManager.PERMISSION_GRANTED) {
8826                    return null;
8827                }
8828                String ppwperm = pp.getWritePermission();
8829                if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
8830                        cpi.applicationInfo.uid, cpi.exported)
8831                        == PackageManager.PERMISSION_GRANTED) {
8832                    return null;
8833                }
8834            }
8835        }
8836        if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
8837            return null;
8838        }
8839
8840        String msg;
8841        if (!cpi.exported) {
8842            msg = "Permission Denial: opening provider " + cpi.name
8843                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8844                    + ", uid=" + callingUid + ") that is not exported from uid "
8845                    + cpi.applicationInfo.uid;
8846        } else {
8847            msg = "Permission Denial: opening provider " + cpi.name
8848                    + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
8849                    + ", uid=" + callingUid + ") requires "
8850                    + cpi.readPermission + " or " + cpi.writePermission;
8851        }
8852        Slog.w(TAG, msg);
8853        return msg;
8854    }
8855
8856    /**
8857     * Returns if the ContentProvider has granted a uri to callingUid
8858     */
8859    boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
8860        final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8861        if (perms != null) {
8862            for (int i=perms.size()-1; i>=0; i--) {
8863                GrantUri grantUri = perms.keyAt(i);
8864                if (grantUri.sourceUserId == userId || !checkUser) {
8865                    if (matchesProvider(grantUri.uri, cpi)) {
8866                        return true;
8867                    }
8868                }
8869            }
8870        }
8871        return false;
8872    }
8873
8874    /**
8875     * Returns true if the uri authority is one of the authorities specified in the provider.
8876     */
8877    boolean matchesProvider(Uri uri, ProviderInfo cpi) {
8878        String uriAuth = uri.getAuthority();
8879        String cpiAuth = cpi.authority;
8880        if (cpiAuth.indexOf(';') == -1) {
8881            return cpiAuth.equals(uriAuth);
8882        }
8883        String[] cpiAuths = cpiAuth.split(";");
8884        int length = cpiAuths.length;
8885        for (int i = 0; i < length; i++) {
8886            if (cpiAuths[i].equals(uriAuth)) return true;
8887        }
8888        return false;
8889    }
8890
8891    ContentProviderConnection incProviderCountLocked(ProcessRecord r,
8892            final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8893        if (r != null) {
8894            for (int i=0; i<r.conProviders.size(); i++) {
8895                ContentProviderConnection conn = r.conProviders.get(i);
8896                if (conn.provider == cpr) {
8897                    if (DEBUG_PROVIDER) Slog.v(TAG,
8898                            "Adding provider requested by "
8899                            + r.processName + " from process "
8900                            + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8901                            + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8902                    if (stable) {
8903                        conn.stableCount++;
8904                        conn.numStableIncs++;
8905                    } else {
8906                        conn.unstableCount++;
8907                        conn.numUnstableIncs++;
8908                    }
8909                    return conn;
8910                }
8911            }
8912            ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
8913            if (stable) {
8914                conn.stableCount = 1;
8915                conn.numStableIncs = 1;
8916            } else {
8917                conn.unstableCount = 1;
8918                conn.numUnstableIncs = 1;
8919            }
8920            cpr.connections.add(conn);
8921            r.conProviders.add(conn);
8922            return conn;
8923        }
8924        cpr.addExternalProcessHandleLocked(externalProcessToken);
8925        return null;
8926    }
8927
8928    boolean decProviderCountLocked(ContentProviderConnection conn,
8929            ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
8930        if (conn != null) {
8931            cpr = conn.provider;
8932            if (DEBUG_PROVIDER) Slog.v(TAG,
8933                    "Removing provider requested by "
8934                    + conn.client.processName + " from process "
8935                    + cpr.info.processName + ": " + cpr.name.flattenToShortString()
8936                    + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
8937            if (stable) {
8938                conn.stableCount--;
8939            } else {
8940                conn.unstableCount--;
8941            }
8942            if (conn.stableCount == 0 && conn.unstableCount == 0) {
8943                cpr.connections.remove(conn);
8944                conn.client.conProviders.remove(conn);
8945                return true;
8946            }
8947            return false;
8948        }
8949        cpr.removeExternalProcessHandleLocked(externalProcessToken);
8950        return false;
8951    }
8952
8953    private void checkTime(long startTime, String where) {
8954        long now = SystemClock.elapsedRealtime();
8955        if ((now-startTime) > 1000) {
8956            // If we are taking more than a second, log about it.
8957            Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
8958        }
8959    }
8960
8961    private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
8962            String name, IBinder token, boolean stable, int userId) {
8963        ContentProviderRecord cpr;
8964        ContentProviderConnection conn = null;
8965        ProviderInfo cpi = null;
8966
8967        synchronized(this) {
8968            long startTime = SystemClock.elapsedRealtime();
8969
8970            ProcessRecord r = null;
8971            if (caller != null) {
8972                r = getRecordForAppLocked(caller);
8973                if (r == null) {
8974                    throw new SecurityException(
8975                            "Unable to find app for caller " + caller
8976                          + " (pid=" + Binder.getCallingPid()
8977                          + ") when getting content provider " + name);
8978                }
8979            }
8980
8981            boolean checkCrossUser = true;
8982
8983            checkTime(startTime, "getContentProviderImpl: getProviderByName");
8984
8985            // First check if this content provider has been published...
8986            cpr = mProviderMap.getProviderByName(name, userId);
8987            // If that didn't work, check if it exists for user 0 and then
8988            // verify that it's a singleton provider before using it.
8989            if (cpr == null && userId != UserHandle.USER_OWNER) {
8990                cpr = mProviderMap.getProviderByName(name, UserHandle.USER_OWNER);
8991                if (cpr != null) {
8992                    cpi = cpr.info;
8993                    if (isSingleton(cpi.processName, cpi.applicationInfo,
8994                            cpi.name, cpi.flags)
8995                            && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
8996                        userId = UserHandle.USER_OWNER;
8997                        checkCrossUser = false;
8998                    } else {
8999                        cpr = null;
9000                        cpi = null;
9001                    }
9002                }
9003            }
9004
9005            boolean providerRunning = cpr != null;
9006            if (providerRunning) {
9007                cpi = cpr.info;
9008                String msg;
9009                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9010                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
9011                        != null) {
9012                    throw new SecurityException(msg);
9013                }
9014                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9015
9016                if (r != null && cpr.canRunHere(r)) {
9017                    // This provider has been published or is in the process
9018                    // of being published...  but it is also allowed to run
9019                    // in the caller's process, so don't make a connection
9020                    // and just let the caller instantiate its own instance.
9021                    ContentProviderHolder holder = cpr.newHolder(null);
9022                    // don't give caller the provider object, it needs
9023                    // to make its own.
9024                    holder.provider = null;
9025                    return holder;
9026                }
9027
9028                final long origId = Binder.clearCallingIdentity();
9029
9030                checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
9031
9032                // In this case the provider instance already exists, so we can
9033                // return it right away.
9034                conn = incProviderCountLocked(r, cpr, token, stable);
9035                if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
9036                    if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
9037                        // If this is a perceptible app accessing the provider,
9038                        // make sure to count it as being accessed and thus
9039                        // back up on the LRU list.  This is good because
9040                        // content providers are often expensive to start.
9041                        checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
9042                        updateLruProcessLocked(cpr.proc, false, null);
9043                        checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
9044                    }
9045                }
9046
9047                if (cpr.proc != null) {
9048                    if (false) {
9049                        if (cpr.name.flattenToShortString().equals(
9050                                "com.android.providers.calendar/.CalendarProvider2")) {
9051                            Slog.v(TAG, "****************** KILLING "
9052                                + cpr.name.flattenToShortString());
9053                            Process.killProcess(cpr.proc.pid);
9054                        }
9055                    }
9056                    checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
9057                    boolean success = updateOomAdjLocked(cpr.proc);
9058                    checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
9059                    if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
9060                    // NOTE: there is still a race here where a signal could be
9061                    // pending on the process even though we managed to update its
9062                    // adj level.  Not sure what to do about this, but at least
9063                    // the race is now smaller.
9064                    if (!success) {
9065                        // Uh oh...  it looks like the provider's process
9066                        // has been killed on us.  We need to wait for a new
9067                        // process to be started, and make sure its death
9068                        // doesn't kill our process.
9069                        Slog.i(TAG,
9070                                "Existing provider " + cpr.name.flattenToShortString()
9071                                + " is crashing; detaching " + r);
9072                        boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
9073                        checkTime(startTime, "getContentProviderImpl: before appDied");
9074                        appDiedLocked(cpr.proc);
9075                        checkTime(startTime, "getContentProviderImpl: after appDied");
9076                        if (!lastRef) {
9077                            // This wasn't the last ref our process had on
9078                            // the provider...  we have now been killed, bail.
9079                            return null;
9080                        }
9081                        providerRunning = false;
9082                        conn = null;
9083                    }
9084                }
9085
9086                Binder.restoreCallingIdentity(origId);
9087            }
9088
9089            boolean singleton;
9090            if (!providerRunning) {
9091                try {
9092                    checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
9093                    cpi = AppGlobals.getPackageManager().
9094                        resolveContentProvider(name,
9095                            STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
9096                    checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
9097                } catch (RemoteException ex) {
9098                }
9099                if (cpi == null) {
9100                    return null;
9101                }
9102                // If the provider is a singleton AND
9103                // (it's a call within the same user || the provider is a
9104                // privileged app)
9105                // Then allow connecting to the singleton provider
9106                singleton = isSingleton(cpi.processName, cpi.applicationInfo,
9107                        cpi.name, cpi.flags)
9108                        && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
9109                if (singleton) {
9110                    userId = UserHandle.USER_OWNER;
9111                }
9112                cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
9113                checkTime(startTime, "getContentProviderImpl: got app info for user");
9114
9115                String msg;
9116                checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
9117                if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
9118                        != null) {
9119                    throw new SecurityException(msg);
9120                }
9121                checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
9122
9123                if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
9124                        && !cpi.processName.equals("system")) {
9125                    // If this content provider does not run in the system
9126                    // process, and the system is not yet ready to run other
9127                    // processes, then fail fast instead of hanging.
9128                    throw new IllegalArgumentException(
9129                            "Attempt to launch content provider before system ready");
9130                }
9131
9132                // Make sure that the user who owns this provider is started.  If not,
9133                // we don't want to allow it to run.
9134                if (mStartedUsers.get(userId) == null) {
9135                    Slog.w(TAG, "Unable to launch app "
9136                            + cpi.applicationInfo.packageName + "/"
9137                            + cpi.applicationInfo.uid + " for provider "
9138                            + name + ": user " + userId + " is stopped");
9139                    return null;
9140                }
9141
9142                ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
9143                checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
9144                cpr = mProviderMap.getProviderByClass(comp, userId);
9145                checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
9146                final boolean firstClass = cpr == null;
9147                if (firstClass) {
9148                    try {
9149                        checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
9150                        ApplicationInfo ai =
9151                            AppGlobals.getPackageManager().
9152                                getApplicationInfo(
9153                                        cpi.applicationInfo.packageName,
9154                                        STOCK_PM_FLAGS, userId);
9155                        checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
9156                        if (ai == null) {
9157                            Slog.w(TAG, "No package info for content provider "
9158                                    + cpi.name);
9159                            return null;
9160                        }
9161                        ai = getAppInfoForUser(ai, userId);
9162                        cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
9163                    } catch (RemoteException ex) {
9164                        // pm is in same process, this will never happen.
9165                    }
9166                }
9167
9168                checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
9169
9170                if (r != null && cpr.canRunHere(r)) {
9171                    // If this is a multiprocess provider, then just return its
9172                    // info and allow the caller to instantiate it.  Only do
9173                    // this if the provider is the same user as the caller's
9174                    // process, or can run as root (so can be in any process).
9175                    return cpr.newHolder(null);
9176                }
9177
9178                if (DEBUG_PROVIDER) {
9179                    RuntimeException e = new RuntimeException("here");
9180                    Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + (r != null ? r.uid : null)
9181                          + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
9182                }
9183
9184                // This is single process, and our app is now connecting to it.
9185                // See if we are already in the process of launching this
9186                // provider.
9187                final int N = mLaunchingProviders.size();
9188                int i;
9189                for (i=0; i<N; i++) {
9190                    if (mLaunchingProviders.get(i) == cpr) {
9191                        break;
9192                    }
9193                }
9194
9195                // If the provider is not already being launched, then get it
9196                // started.
9197                if (i >= N) {
9198                    final long origId = Binder.clearCallingIdentity();
9199
9200                    try {
9201                        // Content provider is now in use, its package can't be stopped.
9202                        try {
9203                            checkTime(startTime, "getContentProviderImpl: before set stopped state");
9204                            AppGlobals.getPackageManager().setPackageStoppedState(
9205                                    cpr.appInfo.packageName, false, userId);
9206                            checkTime(startTime, "getContentProviderImpl: after set stopped state");
9207                        } catch (RemoteException e) {
9208                        } catch (IllegalArgumentException e) {
9209                            Slog.w(TAG, "Failed trying to unstop package "
9210                                    + cpr.appInfo.packageName + ": " + e);
9211                        }
9212
9213                        // Use existing process if already started
9214                        checkTime(startTime, "getContentProviderImpl: looking for process record");
9215                        ProcessRecord proc = getProcessRecordLocked(
9216                                cpi.processName, cpr.appInfo.uid, false);
9217                        if (proc != null && proc.thread != null) {
9218                            if (DEBUG_PROVIDER) {
9219                                Slog.d(TAG, "Installing in existing process " + proc);
9220                            }
9221                            checkTime(startTime, "getContentProviderImpl: scheduling install");
9222                            proc.pubProviders.put(cpi.name, cpr);
9223                            try {
9224                                proc.thread.scheduleInstallProvider(cpi);
9225                            } catch (RemoteException e) {
9226                            }
9227                        } else {
9228                            checkTime(startTime, "getContentProviderImpl: before start process");
9229                            proc = startProcessLocked(cpi.processName,
9230                                    cpr.appInfo, false, 0, "content provider",
9231                                    new ComponentName(cpi.applicationInfo.packageName,
9232                                            cpi.name), false, false, false);
9233                            checkTime(startTime, "getContentProviderImpl: after start process");
9234                            if (proc == null) {
9235                                Slog.w(TAG, "Unable to launch app "
9236                                        + cpi.applicationInfo.packageName + "/"
9237                                        + cpi.applicationInfo.uid + " for provider "
9238                                        + name + ": process is bad");
9239                                return null;
9240                            }
9241                        }
9242                        cpr.launchingApp = proc;
9243                        mLaunchingProviders.add(cpr);
9244                    } finally {
9245                        Binder.restoreCallingIdentity(origId);
9246                    }
9247                }
9248
9249                checkTime(startTime, "getContentProviderImpl: updating data structures");
9250
9251                // Make sure the provider is published (the same provider class
9252                // may be published under multiple names).
9253                if (firstClass) {
9254                    mProviderMap.putProviderByClass(comp, cpr);
9255                }
9256
9257                mProviderMap.putProviderByName(name, cpr);
9258                conn = incProviderCountLocked(r, cpr, token, stable);
9259                if (conn != null) {
9260                    conn.waiting = true;
9261                }
9262            }
9263            checkTime(startTime, "getContentProviderImpl: done!");
9264        }
9265
9266        // Wait for the provider to be published...
9267        synchronized (cpr) {
9268            while (cpr.provider == null) {
9269                if (cpr.launchingApp == null) {
9270                    Slog.w(TAG, "Unable to launch app "
9271                            + cpi.applicationInfo.packageName + "/"
9272                            + cpi.applicationInfo.uid + " for provider "
9273                            + name + ": launching app became null");
9274                    EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
9275                            UserHandle.getUserId(cpi.applicationInfo.uid),
9276                            cpi.applicationInfo.packageName,
9277                            cpi.applicationInfo.uid, name);
9278                    return null;
9279                }
9280                try {
9281                    if (DEBUG_MU) {
9282                        Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
9283                                + cpr.launchingApp);
9284                    }
9285                    if (conn != null) {
9286                        conn.waiting = true;
9287                    }
9288                    cpr.wait();
9289                } catch (InterruptedException ex) {
9290                } finally {
9291                    if (conn != null) {
9292                        conn.waiting = false;
9293                    }
9294                }
9295            }
9296        }
9297        return cpr != null ? cpr.newHolder(conn) : null;
9298    }
9299
9300    @Override
9301    public final ContentProviderHolder getContentProvider(
9302            IApplicationThread caller, String name, int userId, boolean stable) {
9303        enforceNotIsolatedCaller("getContentProvider");
9304        if (caller == null) {
9305            String msg = "null IApplicationThread when getting content provider "
9306                    + name;
9307            Slog.w(TAG, msg);
9308            throw new SecurityException(msg);
9309        }
9310        // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
9311        // with cross-user grant.
9312        return getContentProviderImpl(caller, name, null, stable, userId);
9313    }
9314
9315    public ContentProviderHolder getContentProviderExternal(
9316            String name, int userId, IBinder token) {
9317        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9318            "Do not have permission in call getContentProviderExternal()");
9319        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
9320                false, ALLOW_FULL_ONLY, "getContentProvider", null);
9321        return getContentProviderExternalUnchecked(name, token, userId);
9322    }
9323
9324    private ContentProviderHolder getContentProviderExternalUnchecked(String name,
9325            IBinder token, int userId) {
9326        return getContentProviderImpl(null, name, token, true, userId);
9327    }
9328
9329    /**
9330     * Drop a content provider from a ProcessRecord's bookkeeping
9331     */
9332    public void removeContentProvider(IBinder connection, boolean stable) {
9333        enforceNotIsolatedCaller("removeContentProvider");
9334        long ident = Binder.clearCallingIdentity();
9335        try {
9336            synchronized (this) {
9337                ContentProviderConnection conn;
9338                try {
9339                    conn = (ContentProviderConnection)connection;
9340                } catch (ClassCastException e) {
9341                    String msg ="removeContentProvider: " + connection
9342                            + " not a ContentProviderConnection";
9343                    Slog.w(TAG, msg);
9344                    throw new IllegalArgumentException(msg);
9345                }
9346                if (conn == null) {
9347                    throw new NullPointerException("connection is null");
9348                }
9349                if (decProviderCountLocked(conn, null, null, stable)) {
9350                    updateOomAdjLocked();
9351                }
9352            }
9353        } finally {
9354            Binder.restoreCallingIdentity(ident);
9355        }
9356    }
9357
9358    public void removeContentProviderExternal(String name, IBinder token) {
9359        enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
9360            "Do not have permission in call removeContentProviderExternal()");
9361        removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
9362    }
9363
9364    private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
9365        synchronized (this) {
9366            ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
9367            if(cpr == null) {
9368                //remove from mProvidersByClass
9369                if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
9370                return;
9371            }
9372
9373            //update content provider record entry info
9374            ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
9375            ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
9376            if (localCpr.hasExternalProcessHandles()) {
9377                if (localCpr.removeExternalProcessHandleLocked(token)) {
9378                    updateOomAdjLocked();
9379                } else {
9380                    Slog.e(TAG, "Attmpt to remove content provider " + localCpr
9381                            + " with no external reference for token: "
9382                            + token + ".");
9383                }
9384            } else {
9385                Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
9386                        + " with no external references.");
9387            }
9388        }
9389    }
9390
9391    public final void publishContentProviders(IApplicationThread caller,
9392            List<ContentProviderHolder> providers) {
9393        if (providers == null) {
9394            return;
9395        }
9396
9397        enforceNotIsolatedCaller("publishContentProviders");
9398        synchronized (this) {
9399            final ProcessRecord r = getRecordForAppLocked(caller);
9400            if (DEBUG_MU)
9401                Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
9402            if (r == null) {
9403                throw new SecurityException(
9404                        "Unable to find app for caller " + caller
9405                      + " (pid=" + Binder.getCallingPid()
9406                      + ") when publishing content providers");
9407            }
9408
9409            final long origId = Binder.clearCallingIdentity();
9410
9411            final int N = providers.size();
9412            for (int i=0; i<N; i++) {
9413                ContentProviderHolder src = providers.get(i);
9414                if (src == null || src.info == null || src.provider == null) {
9415                    continue;
9416                }
9417                ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9418                if (DEBUG_MU)
9419                    Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
9420                if (dst != null) {
9421                    ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9422                    mProviderMap.putProviderByClass(comp, dst);
9423                    String names[] = dst.info.authority.split(";");
9424                    for (int j = 0; j < names.length; j++) {
9425                        mProviderMap.putProviderByName(names[j], dst);
9426                    }
9427
9428                    int NL = mLaunchingProviders.size();
9429                    int j;
9430                    for (j=0; j<NL; j++) {
9431                        if (mLaunchingProviders.get(j) == dst) {
9432                            mLaunchingProviders.remove(j);
9433                            j--;
9434                            NL--;
9435                        }
9436                    }
9437                    synchronized (dst) {
9438                        dst.provider = src.provider;
9439                        dst.proc = r;
9440                        dst.notifyAll();
9441                    }
9442                    updateOomAdjLocked(r);
9443                }
9444            }
9445
9446            Binder.restoreCallingIdentity(origId);
9447        }
9448    }
9449
9450    public boolean refContentProvider(IBinder connection, int stable, int unstable) {
9451        ContentProviderConnection conn;
9452        try {
9453            conn = (ContentProviderConnection)connection;
9454        } catch (ClassCastException e) {
9455            String msg ="refContentProvider: " + connection
9456                    + " not a ContentProviderConnection";
9457            Slog.w(TAG, msg);
9458            throw new IllegalArgumentException(msg);
9459        }
9460        if (conn == null) {
9461            throw new NullPointerException("connection is null");
9462        }
9463
9464        synchronized (this) {
9465            if (stable > 0) {
9466                conn.numStableIncs += stable;
9467            }
9468            stable = conn.stableCount + stable;
9469            if (stable < 0) {
9470                throw new IllegalStateException("stableCount < 0: " + stable);
9471            }
9472
9473            if (unstable > 0) {
9474                conn.numUnstableIncs += unstable;
9475            }
9476            unstable = conn.unstableCount + unstable;
9477            if (unstable < 0) {
9478                throw new IllegalStateException("unstableCount < 0: " + unstable);
9479            }
9480
9481            if ((stable+unstable) <= 0) {
9482                throw new IllegalStateException("ref counts can't go to zero here: stable="
9483                        + stable + " unstable=" + unstable);
9484            }
9485            conn.stableCount = stable;
9486            conn.unstableCount = unstable;
9487            return !conn.dead;
9488        }
9489    }
9490
9491    public void unstableProviderDied(IBinder connection) {
9492        ContentProviderConnection conn;
9493        try {
9494            conn = (ContentProviderConnection)connection;
9495        } catch (ClassCastException e) {
9496            String msg ="refContentProvider: " + connection
9497                    + " not a ContentProviderConnection";
9498            Slog.w(TAG, msg);
9499            throw new IllegalArgumentException(msg);
9500        }
9501        if (conn == null) {
9502            throw new NullPointerException("connection is null");
9503        }
9504
9505        // Safely retrieve the content provider associated with the connection.
9506        IContentProvider provider;
9507        synchronized (this) {
9508            provider = conn.provider.provider;
9509        }
9510
9511        if (provider == null) {
9512            // Um, yeah, we're way ahead of you.
9513            return;
9514        }
9515
9516        // Make sure the caller is being honest with us.
9517        if (provider.asBinder().pingBinder()) {
9518            // Er, no, still looks good to us.
9519            synchronized (this) {
9520                Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
9521                        + " says " + conn + " died, but we don't agree");
9522                return;
9523            }
9524        }
9525
9526        // Well look at that!  It's dead!
9527        synchronized (this) {
9528            if (conn.provider.provider != provider) {
9529                // But something changed...  good enough.
9530                return;
9531            }
9532
9533            ProcessRecord proc = conn.provider.proc;
9534            if (proc == null || proc.thread == null) {
9535                // Seems like the process is already cleaned up.
9536                return;
9537            }
9538
9539            // As far as we're concerned, this is just like receiving a
9540            // death notification...  just a bit prematurely.
9541            Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
9542                    + ") early provider death");
9543            final long ident = Binder.clearCallingIdentity();
9544            try {
9545                appDiedLocked(proc);
9546            } finally {
9547                Binder.restoreCallingIdentity(ident);
9548            }
9549        }
9550    }
9551
9552    @Override
9553    public void appNotRespondingViaProvider(IBinder connection) {
9554        enforceCallingPermission(
9555                android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
9556
9557        final ContentProviderConnection conn = (ContentProviderConnection) connection;
9558        if (conn == null) {
9559            Slog.w(TAG, "ContentProviderConnection is null");
9560            return;
9561        }
9562
9563        final ProcessRecord host = conn.provider.proc;
9564        if (host == null) {
9565            Slog.w(TAG, "Failed to find hosting ProcessRecord");
9566            return;
9567        }
9568
9569        final long token = Binder.clearCallingIdentity();
9570        try {
9571            appNotResponding(host, null, null, false, "ContentProvider not responding");
9572        } finally {
9573            Binder.restoreCallingIdentity(token);
9574        }
9575    }
9576
9577    public final void installSystemProviders() {
9578        List<ProviderInfo> providers;
9579        synchronized (this) {
9580            ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
9581            providers = generateApplicationProvidersLocked(app);
9582            if (providers != null) {
9583                for (int i=providers.size()-1; i>=0; i--) {
9584                    ProviderInfo pi = (ProviderInfo)providers.get(i);
9585                    if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
9586                        Slog.w(TAG, "Not installing system proc provider " + pi.name
9587                                + ": not system .apk");
9588                        providers.remove(i);
9589                    }
9590                }
9591            }
9592        }
9593        if (providers != null) {
9594            mSystemThread.installSystemProviders(providers);
9595        }
9596
9597        mCoreSettingsObserver = new CoreSettingsObserver(this);
9598
9599        //mUsageStatsService.monitorPackages();
9600    }
9601
9602    /**
9603     * Allows apps to retrieve the MIME type of a URI.
9604     * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
9605     * users, then it does not need permission to access the ContentProvider.
9606     * Either, it needs cross-user uri grants.
9607     *
9608     * CTS tests for this functionality can be run with "runtest cts-appsecurity".
9609     *
9610     * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
9611     *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
9612     */
9613    public String getProviderMimeType(Uri uri, int userId) {
9614        enforceNotIsolatedCaller("getProviderMimeType");
9615        final String name = uri.getAuthority();
9616        int callingUid = Binder.getCallingUid();
9617        int callingPid = Binder.getCallingPid();
9618        long ident = 0;
9619        boolean clearedIdentity = false;
9620        userId = unsafeConvertIncomingUser(userId);
9621        if (UserHandle.getUserId(callingUid) != userId) {
9622            if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
9623                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
9624                    || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
9625                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
9626                clearedIdentity = true;
9627                ident = Binder.clearCallingIdentity();
9628            }
9629        }
9630        ContentProviderHolder holder = null;
9631        try {
9632            holder = getContentProviderExternalUnchecked(name, null, userId);
9633            if (holder != null) {
9634                return holder.provider.getType(uri);
9635            }
9636        } catch (RemoteException e) {
9637            Log.w(TAG, "Content provider dead retrieving " + uri, e);
9638            return null;
9639        } finally {
9640            // We need to clear the identity to call removeContentProviderExternalUnchecked
9641            if (!clearedIdentity) {
9642                ident = Binder.clearCallingIdentity();
9643            }
9644            try {
9645                if (holder != null) {
9646                    removeContentProviderExternalUnchecked(name, null, userId);
9647                }
9648            } finally {
9649                Binder.restoreCallingIdentity(ident);
9650            }
9651        }
9652
9653        return null;
9654    }
9655
9656    // =========================================================
9657    // GLOBAL MANAGEMENT
9658    // =========================================================
9659
9660    final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
9661            boolean isolated, int isolatedUid) {
9662        String proc = customProcess != null ? customProcess : info.processName;
9663        BatteryStatsImpl.Uid.Proc ps = null;
9664        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9665        int uid = info.uid;
9666        if (isolated) {
9667            if (isolatedUid == 0) {
9668                int userId = UserHandle.getUserId(uid);
9669                int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
9670                while (true) {
9671                    if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
9672                            || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
9673                        mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
9674                    }
9675                    uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
9676                    mNextIsolatedProcessUid++;
9677                    if (mIsolatedProcesses.indexOfKey(uid) < 0) {
9678                        // No process for this uid, use it.
9679                        break;
9680                    }
9681                    stepsLeft--;
9682                    if (stepsLeft <= 0) {
9683                        return null;
9684                    }
9685                }
9686            } else {
9687                // Special case for startIsolatedProcess (internal only), where
9688                // the uid of the isolated process is specified by the caller.
9689                uid = isolatedUid;
9690            }
9691        }
9692        return new ProcessRecord(stats, info, proc, uid);
9693    }
9694
9695    final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
9696            String abiOverride) {
9697        ProcessRecord app;
9698        if (!isolated) {
9699            app = getProcessRecordLocked(info.processName, info.uid, true);
9700        } else {
9701            app = null;
9702        }
9703
9704        if (app == null) {
9705            app = newProcessRecordLocked(info, null, isolated, 0);
9706            mProcessNames.put(info.processName, app.uid, app);
9707            if (isolated) {
9708                mIsolatedProcesses.put(app.uid, app);
9709            }
9710            updateLruProcessLocked(app, false, null);
9711            updateOomAdjLocked();
9712        }
9713
9714        // This package really, really can not be stopped.
9715        try {
9716            AppGlobals.getPackageManager().setPackageStoppedState(
9717                    info.packageName, false, UserHandle.getUserId(app.uid));
9718        } catch (RemoteException e) {
9719        } catch (IllegalArgumentException e) {
9720            Slog.w(TAG, "Failed trying to unstop package "
9721                    + info.packageName + ": " + e);
9722        }
9723
9724        if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
9725                == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
9726            app.persistent = true;
9727            app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
9728        }
9729        if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
9730            mPersistentStartingProcesses.add(app);
9731            startProcessLocked(app, "added application", app.processName, abiOverride,
9732                    null /* entryPoint */, null /* entryPointArgs */);
9733        }
9734
9735        return app;
9736    }
9737
9738    public void unhandledBack() {
9739        enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
9740                "unhandledBack()");
9741
9742        synchronized(this) {
9743            final long origId = Binder.clearCallingIdentity();
9744            try {
9745                getFocusedStack().unhandledBackLocked();
9746            } finally {
9747                Binder.restoreCallingIdentity(origId);
9748            }
9749        }
9750    }
9751
9752    public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
9753        enforceNotIsolatedCaller("openContentUri");
9754        final int userId = UserHandle.getCallingUserId();
9755        String name = uri.getAuthority();
9756        ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
9757        ParcelFileDescriptor pfd = null;
9758        if (cph != null) {
9759            // We record the binder invoker's uid in thread-local storage before
9760            // going to the content provider to open the file.  Later, in the code
9761            // that handles all permissions checks, we look for this uid and use
9762            // that rather than the Activity Manager's own uid.  The effect is that
9763            // we do the check against the caller's permissions even though it looks
9764            // to the content provider like the Activity Manager itself is making
9765            // the request.
9766            sCallerIdentity.set(new Identity(
9767                    Binder.getCallingPid(), Binder.getCallingUid()));
9768            try {
9769                pfd = cph.provider.openFile(null, uri, "r", null);
9770            } catch (FileNotFoundException e) {
9771                // do nothing; pfd will be returned null
9772            } finally {
9773                // Ensure that whatever happens, we clean up the identity state
9774                sCallerIdentity.remove();
9775            }
9776
9777            // We've got the fd now, so we're done with the provider.
9778            removeContentProviderExternalUnchecked(name, null, userId);
9779        } else {
9780            Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
9781        }
9782        return pfd;
9783    }
9784
9785    // Actually is sleeping or shutting down or whatever else in the future
9786    // is an inactive state.
9787    public boolean isSleepingOrShuttingDown() {
9788        return mSleeping || mShuttingDown;
9789    }
9790
9791    public boolean isSleeping() {
9792        return mSleeping;
9793    }
9794
9795    void goingToSleep() {
9796        synchronized(this) {
9797            mWentToSleep = true;
9798            updateEventDispatchingLocked();
9799            goToSleepIfNeededLocked();
9800        }
9801    }
9802
9803    void finishRunningVoiceLocked() {
9804        if (mRunningVoice) {
9805            mRunningVoice = false;
9806            goToSleepIfNeededLocked();
9807        }
9808    }
9809
9810    void goToSleepIfNeededLocked() {
9811        if (mWentToSleep && !mRunningVoice) {
9812            if (!mSleeping) {
9813                mSleeping = true;
9814                mStackSupervisor.goingToSleepLocked();
9815
9816                // Initialize the wake times of all processes.
9817                checkExcessivePowerUsageLocked(false);
9818                mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9819                Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
9820                mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
9821            }
9822        }
9823    }
9824
9825    void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
9826        if (task != null && task.stack != null && task.stack.isHomeStack()) {
9827            // Never persist the home stack.
9828            return;
9829        }
9830        mTaskPersister.wakeup(task, flush);
9831    }
9832
9833    @Override
9834    public boolean shutdown(int timeout) {
9835        if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
9836                != PackageManager.PERMISSION_GRANTED) {
9837            throw new SecurityException("Requires permission "
9838                    + android.Manifest.permission.SHUTDOWN);
9839        }
9840
9841        boolean timedout = false;
9842
9843        synchronized(this) {
9844            mShuttingDown = true;
9845            updateEventDispatchingLocked();
9846            timedout = mStackSupervisor.shutdownLocked(timeout);
9847        }
9848
9849        mAppOpsService.shutdown();
9850        if (mUsageStatsService != null) {
9851            mUsageStatsService.prepareShutdown();
9852        }
9853        mBatteryStatsService.shutdown();
9854        synchronized (this) {
9855            mProcessStats.shutdownLocked();
9856        }
9857        notifyTaskPersisterLocked(null, true);
9858
9859        return timedout;
9860    }
9861
9862    public final void activitySlept(IBinder token) {
9863        if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
9864
9865        final long origId = Binder.clearCallingIdentity();
9866
9867        synchronized (this) {
9868            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
9869            if (r != null) {
9870                mStackSupervisor.activitySleptLocked(r);
9871            }
9872        }
9873
9874        Binder.restoreCallingIdentity(origId);
9875    }
9876
9877    void logLockScreen(String msg) {
9878        if (DEBUG_LOCKSCREEN) Slog.d(TAG, Debug.getCallers(2) + ":" + msg +
9879                " mLockScreenShown=" + mLockScreenShown + " mWentToSleep=" +
9880                mWentToSleep + " mSleeping=" + mSleeping);
9881    }
9882
9883    private void comeOutOfSleepIfNeededLocked() {
9884        if ((!mWentToSleep && !mLockScreenShown) || mRunningVoice) {
9885            if (mSleeping) {
9886                mSleeping = false;
9887                mStackSupervisor.comeOutOfSleepIfNeededLocked();
9888            }
9889        }
9890    }
9891
9892    void wakingUp() {
9893        synchronized(this) {
9894            mWentToSleep = false;
9895            updateEventDispatchingLocked();
9896            comeOutOfSleepIfNeededLocked();
9897        }
9898    }
9899
9900    void startRunningVoiceLocked() {
9901        if (!mRunningVoice) {
9902            mRunningVoice = true;
9903            comeOutOfSleepIfNeededLocked();
9904        }
9905    }
9906
9907    private void updateEventDispatchingLocked() {
9908        mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
9909    }
9910
9911    public void setLockScreenShown(boolean shown) {
9912        if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
9913                != PackageManager.PERMISSION_GRANTED) {
9914            throw new SecurityException("Requires permission "
9915                    + android.Manifest.permission.DEVICE_POWER);
9916        }
9917
9918        synchronized(this) {
9919            long ident = Binder.clearCallingIdentity();
9920            try {
9921                if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
9922                mLockScreenShown = shown;
9923                comeOutOfSleepIfNeededLocked();
9924            } finally {
9925                Binder.restoreCallingIdentity(ident);
9926            }
9927        }
9928    }
9929
9930    @Override
9931    public void stopAppSwitches() {
9932        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9933                != PackageManager.PERMISSION_GRANTED) {
9934            throw new SecurityException("Requires permission "
9935                    + android.Manifest.permission.STOP_APP_SWITCHES);
9936        }
9937
9938        synchronized(this) {
9939            mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
9940                    + APP_SWITCH_DELAY_TIME;
9941            mDidAppSwitch = false;
9942            mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9943            Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
9944            mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
9945        }
9946    }
9947
9948    public void resumeAppSwitches() {
9949        if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
9950                != PackageManager.PERMISSION_GRANTED) {
9951            throw new SecurityException("Requires permission "
9952                    + android.Manifest.permission.STOP_APP_SWITCHES);
9953        }
9954
9955        synchronized(this) {
9956            // Note that we don't execute any pending app switches... we will
9957            // let those wait until either the timeout, or the next start
9958            // activity request.
9959            mAppSwitchesAllowedTime = 0;
9960        }
9961    }
9962
9963    boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
9964            String name) {
9965        if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
9966            return true;
9967        }
9968
9969        final int perm = checkComponentPermission(
9970                android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
9971                callingUid, -1, true);
9972        if (perm == PackageManager.PERMISSION_GRANTED) {
9973            return true;
9974        }
9975
9976        Slog.w(TAG, name + " request from " + callingUid + " stopped");
9977        return false;
9978    }
9979
9980    public void setDebugApp(String packageName, boolean waitForDebugger,
9981            boolean persistent) {
9982        enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
9983                "setDebugApp()");
9984
9985        long ident = Binder.clearCallingIdentity();
9986        try {
9987            // Note that this is not really thread safe if there are multiple
9988            // callers into it at the same time, but that's not a situation we
9989            // care about.
9990            if (persistent) {
9991                final ContentResolver resolver = mContext.getContentResolver();
9992                Settings.Global.putString(
9993                    resolver, Settings.Global.DEBUG_APP,
9994                    packageName);
9995                Settings.Global.putInt(
9996                    resolver, Settings.Global.WAIT_FOR_DEBUGGER,
9997                    waitForDebugger ? 1 : 0);
9998            }
9999
10000            synchronized (this) {
10001                if (!persistent) {
10002                    mOrigDebugApp = mDebugApp;
10003                    mOrigWaitForDebugger = mWaitForDebugger;
10004                }
10005                mDebugApp = packageName;
10006                mWaitForDebugger = waitForDebugger;
10007                mDebugTransient = !persistent;
10008                if (packageName != null) {
10009                    forceStopPackageLocked(packageName, -1, false, false, true, true,
10010                            false, UserHandle.USER_ALL, "set debug app");
10011                }
10012            }
10013        } finally {
10014            Binder.restoreCallingIdentity(ident);
10015        }
10016    }
10017
10018    void setOpenGlTraceApp(ApplicationInfo app, String processName) {
10019        synchronized (this) {
10020            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10021            if (!isDebuggable) {
10022                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10023                    throw new SecurityException("Process not debuggable: " + app.packageName);
10024                }
10025            }
10026
10027            mOpenGlTraceApp = processName;
10028        }
10029    }
10030
10031    void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
10032        synchronized (this) {
10033            boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
10034            if (!isDebuggable) {
10035                if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
10036                    throw new SecurityException("Process not debuggable: " + app.packageName);
10037                }
10038            }
10039            mProfileApp = processName;
10040            mProfileFile = profilerInfo.profileFile;
10041            if (mProfileFd != null) {
10042                try {
10043                    mProfileFd.close();
10044                } catch (IOException e) {
10045                }
10046                mProfileFd = null;
10047            }
10048            mProfileFd = profilerInfo.profileFd;
10049            mSamplingInterval = profilerInfo.samplingInterval;
10050            mAutoStopProfiler = profilerInfo.autoStopProfiler;
10051            mProfileType = 0;
10052        }
10053    }
10054
10055    @Override
10056    public void setAlwaysFinish(boolean enabled) {
10057        enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
10058                "setAlwaysFinish()");
10059
10060        Settings.Global.putInt(
10061                mContext.getContentResolver(),
10062                Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
10063
10064        synchronized (this) {
10065            mAlwaysFinishActivities = enabled;
10066        }
10067    }
10068
10069    @Override
10070    public void setActivityController(IActivityController controller) {
10071        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10072                "setActivityController()");
10073        synchronized (this) {
10074            mController = controller;
10075            Watchdog.getInstance().setActivityController(controller);
10076        }
10077    }
10078
10079    @Override
10080    public void setUserIsMonkey(boolean userIsMonkey) {
10081        synchronized (this) {
10082            synchronized (mPidsSelfLocked) {
10083                final int callingPid = Binder.getCallingPid();
10084                ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
10085                if (precessRecord == null) {
10086                    throw new SecurityException("Unknown process: " + callingPid);
10087                }
10088                if (precessRecord.instrumentationUiAutomationConnection  == null) {
10089                    throw new SecurityException("Only an instrumentation process "
10090                            + "with a UiAutomation can call setUserIsMonkey");
10091                }
10092            }
10093            mUserIsMonkey = userIsMonkey;
10094        }
10095    }
10096
10097    @Override
10098    public boolean isUserAMonkey() {
10099        synchronized (this) {
10100            // If there is a controller also implies the user is a monkey.
10101            return (mUserIsMonkey || mController != null);
10102        }
10103    }
10104
10105    public void requestBugReport() {
10106        enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
10107        SystemProperties.set("ctl.start", "bugreport");
10108    }
10109
10110    public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
10111        return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
10112    }
10113
10114    public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
10115        if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
10116            return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
10117        }
10118        return KEY_DISPATCHING_TIMEOUT;
10119    }
10120
10121    @Override
10122    public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
10123        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10124                != PackageManager.PERMISSION_GRANTED) {
10125            throw new SecurityException("Requires permission "
10126                    + android.Manifest.permission.FILTER_EVENTS);
10127        }
10128        ProcessRecord proc;
10129        long timeout;
10130        synchronized (this) {
10131            synchronized (mPidsSelfLocked) {
10132                proc = mPidsSelfLocked.get(pid);
10133            }
10134            timeout = getInputDispatchingTimeoutLocked(proc);
10135        }
10136
10137        if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
10138            return -1;
10139        }
10140
10141        return timeout;
10142    }
10143
10144    /**
10145     * Handle input dispatching timeouts.
10146     * Returns whether input dispatching should be aborted or not.
10147     */
10148    public boolean inputDispatchingTimedOut(final ProcessRecord proc,
10149            final ActivityRecord activity, final ActivityRecord parent,
10150            final boolean aboveSystem, String reason) {
10151        if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
10152                != PackageManager.PERMISSION_GRANTED) {
10153            throw new SecurityException("Requires permission "
10154                    + android.Manifest.permission.FILTER_EVENTS);
10155        }
10156
10157        final String annotation;
10158        if (reason == null) {
10159            annotation = "Input dispatching timed out";
10160        } else {
10161            annotation = "Input dispatching timed out (" + reason + ")";
10162        }
10163
10164        if (proc != null) {
10165            synchronized (this) {
10166                if (proc.debugging) {
10167                    return false;
10168                }
10169
10170                if (mDidDexOpt) {
10171                    // Give more time since we were dexopting.
10172                    mDidDexOpt = false;
10173                    return false;
10174                }
10175
10176                if (proc.instrumentationClass != null) {
10177                    Bundle info = new Bundle();
10178                    info.putString("shortMsg", "keyDispatchingTimedOut");
10179                    info.putString("longMsg", annotation);
10180                    finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
10181                    return true;
10182                }
10183            }
10184            mHandler.post(new Runnable() {
10185                @Override
10186                public void run() {
10187                    appNotResponding(proc, activity, parent, aboveSystem, annotation);
10188                }
10189            });
10190        }
10191
10192        return true;
10193    }
10194
10195    public Bundle getAssistContextExtras(int requestType) {
10196        enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
10197                "getAssistContextExtras()");
10198        PendingAssistExtras pae;
10199        Bundle extras = new Bundle();
10200        synchronized (this) {
10201            ActivityRecord activity = getFocusedStack().mResumedActivity;
10202            if (activity == null) {
10203                Slog.w(TAG, "getAssistContextExtras failed: no resumed activity");
10204                return null;
10205            }
10206            extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
10207            if (activity.app == null || activity.app.thread == null) {
10208                Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
10209                return extras;
10210            }
10211            if (activity.app.pid == Binder.getCallingPid()) {
10212                Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
10213                return extras;
10214            }
10215            pae = new PendingAssistExtras(activity);
10216            try {
10217                activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
10218                        requestType);
10219                mPendingAssistExtras.add(pae);
10220                mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
10221            } catch (RemoteException e) {
10222                Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
10223                return extras;
10224            }
10225        }
10226        synchronized (pae) {
10227            while (!pae.haveResult) {
10228                try {
10229                    pae.wait();
10230                } catch (InterruptedException e) {
10231                }
10232            }
10233            if (pae.result != null) {
10234                extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
10235            }
10236        }
10237        synchronized (this) {
10238            mPendingAssistExtras.remove(pae);
10239            mHandler.removeCallbacks(pae);
10240        }
10241        return extras;
10242    }
10243
10244    public void reportAssistContextExtras(IBinder token, Bundle extras) {
10245        PendingAssistExtras pae = (PendingAssistExtras)token;
10246        synchronized (pae) {
10247            pae.result = extras;
10248            pae.haveResult = true;
10249            pae.notifyAll();
10250        }
10251    }
10252
10253    public void registerProcessObserver(IProcessObserver observer) {
10254        enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
10255                "registerProcessObserver()");
10256        synchronized (this) {
10257            mProcessObservers.register(observer);
10258        }
10259    }
10260
10261    @Override
10262    public void unregisterProcessObserver(IProcessObserver observer) {
10263        synchronized (this) {
10264            mProcessObservers.unregister(observer);
10265        }
10266    }
10267
10268    @Override
10269    public boolean convertFromTranslucent(IBinder token) {
10270        final long origId = Binder.clearCallingIdentity();
10271        try {
10272            synchronized (this) {
10273                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10274                if (r == null) {
10275                    return false;
10276                }
10277                if (r.changeWindowTranslucency(true)) {
10278                    mWindowManager.setAppFullscreen(token, true);
10279                    r.task.stack.releaseBackgroundResources();
10280                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10281                    return true;
10282                }
10283                return false;
10284            }
10285        } finally {
10286            Binder.restoreCallingIdentity(origId);
10287        }
10288    }
10289
10290    @Override
10291    public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
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                int index = r.task.mActivities.lastIndexOf(r);
10300                if (index > 0) {
10301                    ActivityRecord under = r.task.mActivities.get(index - 1);
10302                    under.returningOptions = options;
10303                }
10304                if (r.changeWindowTranslucency(false)) {
10305                    r.task.stack.convertToTranslucent(r);
10306                    mWindowManager.setAppFullscreen(token, false);
10307                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10308                    return true;
10309                } else {
10310                    mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
10311                    return false;
10312                }
10313            }
10314        } finally {
10315            Binder.restoreCallingIdentity(origId);
10316        }
10317    }
10318
10319    @Override
10320    public boolean requestVisibleBehind(IBinder token, boolean visible) {
10321        final long origId = Binder.clearCallingIdentity();
10322        try {
10323            synchronized (this) {
10324                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10325                if (r != null) {
10326                    return mStackSupervisor.requestVisibleBehindLocked(r, visible);
10327                }
10328            }
10329            return false;
10330        } finally {
10331            Binder.restoreCallingIdentity(origId);
10332        }
10333    }
10334
10335    @Override
10336    public boolean isBackgroundVisibleBehind(IBinder token) {
10337        final long origId = Binder.clearCallingIdentity();
10338        try {
10339            synchronized (this) {
10340                final ActivityStack stack = ActivityRecord.getStackLocked(token);
10341                final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
10342                if (ActivityStackSupervisor.DEBUG_VISIBLE_BEHIND) Slog.d(TAG,
10343                        "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
10344                return visible;
10345            }
10346        } finally {
10347            Binder.restoreCallingIdentity(origId);
10348        }
10349    }
10350
10351    @Override
10352    public ActivityOptions getActivityOptions(IBinder token) {
10353        final long origId = Binder.clearCallingIdentity();
10354        try {
10355            synchronized (this) {
10356                final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10357                if (r != null) {
10358                    final ActivityOptions activityOptions = r.pendingOptions;
10359                    r.pendingOptions = null;
10360                    return activityOptions;
10361                }
10362                return null;
10363            }
10364        } finally {
10365            Binder.restoreCallingIdentity(origId);
10366        }
10367    }
10368
10369    @Override
10370    public void setImmersive(IBinder token, boolean immersive) {
10371        synchronized(this) {
10372            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
10373            if (r == null) {
10374                throw new IllegalArgumentException();
10375            }
10376            r.immersive = immersive;
10377
10378            // update associated state if we're frontmost
10379            if (r == mFocusedActivity) {
10380                if (DEBUG_IMMERSIVE) {
10381                    Slog.d(TAG, "Frontmost changed immersion: "+ r);
10382                }
10383                applyUpdateLockStateLocked(r);
10384            }
10385        }
10386    }
10387
10388    @Override
10389    public boolean isImmersive(IBinder token) {
10390        synchronized (this) {
10391            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10392            if (r == null) {
10393                throw new IllegalArgumentException();
10394            }
10395            return r.immersive;
10396        }
10397    }
10398
10399    public boolean isTopActivityImmersive() {
10400        enforceNotIsolatedCaller("startActivity");
10401        synchronized (this) {
10402            ActivityRecord r = getFocusedStack().topRunningActivityLocked(null);
10403            return (r != null) ? r.immersive : false;
10404        }
10405    }
10406
10407    @Override
10408    public boolean isTopOfTask(IBinder token) {
10409        synchronized (this) {
10410            ActivityRecord r = ActivityRecord.isInStackLocked(token);
10411            if (r == null) {
10412                throw new IllegalArgumentException();
10413            }
10414            return r.task.getTopActivity() == r;
10415        }
10416    }
10417
10418    public final void enterSafeMode() {
10419        synchronized(this) {
10420            // It only makes sense to do this before the system is ready
10421            // and started launching other packages.
10422            if (!mSystemReady) {
10423                try {
10424                    AppGlobals.getPackageManager().enterSafeMode();
10425                } catch (RemoteException e) {
10426                }
10427            }
10428
10429            mSafeMode = true;
10430        }
10431    }
10432
10433    public final void showSafeModeOverlay() {
10434        View v = LayoutInflater.from(mContext).inflate(
10435                com.android.internal.R.layout.safe_mode, null);
10436        WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
10437        lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
10438        lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
10439        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
10440        lp.gravity = Gravity.BOTTOM | Gravity.START;
10441        lp.format = v.getBackground().getOpacity();
10442        lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
10443                | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
10444        lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
10445        ((WindowManager)mContext.getSystemService(
10446                Context.WINDOW_SERVICE)).addView(v, lp);
10447    }
10448
10449    public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg) {
10450        if (!(sender instanceof PendingIntentRecord)) {
10451            return;
10452        }
10453        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10454        synchronized (stats) {
10455            if (mBatteryStatsService.isOnBattery()) {
10456                mBatteryStatsService.enforceCallingPermission();
10457                PendingIntentRecord rec = (PendingIntentRecord)sender;
10458                int MY_UID = Binder.getCallingUid();
10459                int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
10460                BatteryStatsImpl.Uid.Pkg pkg =
10461                    stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
10462                            sourcePkg != null ? sourcePkg : rec.key.packageName);
10463                pkg.incWakeupsLocked();
10464            }
10465        }
10466    }
10467
10468    public boolean killPids(int[] pids, String pReason, boolean secure) {
10469        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10470            throw new SecurityException("killPids only available to the system");
10471        }
10472        String reason = (pReason == null) ? "Unknown" : pReason;
10473        // XXX Note: don't acquire main activity lock here, because the window
10474        // manager calls in with its locks held.
10475
10476        boolean killed = false;
10477        synchronized (mPidsSelfLocked) {
10478            int[] types = new int[pids.length];
10479            int worstType = 0;
10480            for (int i=0; i<pids.length; i++) {
10481                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10482                if (proc != null) {
10483                    int type = proc.setAdj;
10484                    types[i] = type;
10485                    if (type > worstType) {
10486                        worstType = type;
10487                    }
10488                }
10489            }
10490
10491            // If the worst oom_adj is somewhere in the cached proc LRU range,
10492            // then constrain it so we will kill all cached procs.
10493            if (worstType < ProcessList.CACHED_APP_MAX_ADJ
10494                    && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
10495                worstType = ProcessList.CACHED_APP_MIN_ADJ;
10496            }
10497
10498            // If this is not a secure call, don't let it kill processes that
10499            // are important.
10500            if (!secure && worstType < ProcessList.SERVICE_ADJ) {
10501                worstType = ProcessList.SERVICE_ADJ;
10502            }
10503
10504            Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
10505            for (int i=0; i<pids.length; i++) {
10506                ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
10507                if (proc == null) {
10508                    continue;
10509                }
10510                int adj = proc.setAdj;
10511                if (adj >= worstType && !proc.killedByAm) {
10512                    proc.kill(reason, true);
10513                    killed = true;
10514                }
10515            }
10516        }
10517        return killed;
10518    }
10519
10520    @Override
10521    public void killUid(int uid, String reason) {
10522        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10523            throw new SecurityException("killUid only available to the system");
10524        }
10525        synchronized (this) {
10526            killPackageProcessesLocked(null, UserHandle.getAppId(uid), UserHandle.getUserId(uid),
10527                    ProcessList.FOREGROUND_APP_ADJ-1, false, true, true, false,
10528                    reason != null ? reason : "kill uid");
10529        }
10530    }
10531
10532    @Override
10533    public boolean killProcessesBelowForeground(String reason) {
10534        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10535            throw new SecurityException("killProcessesBelowForeground() only available to system");
10536        }
10537
10538        return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
10539    }
10540
10541    private boolean killProcessesBelowAdj(int belowAdj, String reason) {
10542        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
10543            throw new SecurityException("killProcessesBelowAdj() only available to system");
10544        }
10545
10546        boolean killed = false;
10547        synchronized (mPidsSelfLocked) {
10548            final int size = mPidsSelfLocked.size();
10549            for (int i = 0; i < size; i++) {
10550                final int pid = mPidsSelfLocked.keyAt(i);
10551                final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10552                if (proc == null) continue;
10553
10554                final int adj = proc.setAdj;
10555                if (adj > belowAdj && !proc.killedByAm) {
10556                    proc.kill(reason, true);
10557                    killed = true;
10558                }
10559            }
10560        }
10561        return killed;
10562    }
10563
10564    @Override
10565    public void hang(final IBinder who, boolean allowRestart) {
10566        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10567                != PackageManager.PERMISSION_GRANTED) {
10568            throw new SecurityException("Requires permission "
10569                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10570        }
10571
10572        final IBinder.DeathRecipient death = new DeathRecipient() {
10573            @Override
10574            public void binderDied() {
10575                synchronized (this) {
10576                    notifyAll();
10577                }
10578            }
10579        };
10580
10581        try {
10582            who.linkToDeath(death, 0);
10583        } catch (RemoteException e) {
10584            Slog.w(TAG, "hang: given caller IBinder is already dead.");
10585            return;
10586        }
10587
10588        synchronized (this) {
10589            Watchdog.getInstance().setAllowRestart(allowRestart);
10590            Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
10591            synchronized (death) {
10592                while (who.isBinderAlive()) {
10593                    try {
10594                        death.wait();
10595                    } catch (InterruptedException e) {
10596                    }
10597                }
10598            }
10599            Watchdog.getInstance().setAllowRestart(true);
10600        }
10601    }
10602
10603    @Override
10604    public void restart() {
10605        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10606                != PackageManager.PERMISSION_GRANTED) {
10607            throw new SecurityException("Requires permission "
10608                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10609        }
10610
10611        Log.i(TAG, "Sending shutdown broadcast...");
10612
10613        BroadcastReceiver br = new BroadcastReceiver() {
10614            @Override public void onReceive(Context context, Intent intent) {
10615                // Now the broadcast is done, finish up the low-level shutdown.
10616                Log.i(TAG, "Shutting down activity manager...");
10617                shutdown(10000);
10618                Log.i(TAG, "Shutdown complete, restarting!");
10619                Process.killProcess(Process.myPid());
10620                System.exit(10);
10621            }
10622        };
10623
10624        // First send the high-level shut down broadcast.
10625        Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
10626        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
10627        intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
10628        /* For now we are not doing a clean shutdown, because things seem to get unhappy.
10629        mContext.sendOrderedBroadcastAsUser(intent,
10630                UserHandle.ALL, null, br, mHandler, 0, null, null);
10631        */
10632        br.onReceive(mContext, intent);
10633    }
10634
10635    private long getLowRamTimeSinceIdle(long now) {
10636        return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
10637    }
10638
10639    @Override
10640    public void performIdleMaintenance() {
10641        if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
10642                != PackageManager.PERMISSION_GRANTED) {
10643            throw new SecurityException("Requires permission "
10644                    + android.Manifest.permission.SET_ACTIVITY_WATCHER);
10645        }
10646
10647        synchronized (this) {
10648            final long now = SystemClock.uptimeMillis();
10649            final long timeSinceLastIdle = now - mLastIdleTime;
10650            final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
10651            mLastIdleTime = now;
10652            mLowRamTimeSinceLastIdle = 0;
10653            if (mLowRamStartTime != 0) {
10654                mLowRamStartTime = now;
10655            }
10656
10657            StringBuilder sb = new StringBuilder(128);
10658            sb.append("Idle maintenance over ");
10659            TimeUtils.formatDuration(timeSinceLastIdle, sb);
10660            sb.append(" low RAM for ");
10661            TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
10662            Slog.i(TAG, sb.toString());
10663
10664            // If at least 1/3 of our time since the last idle period has been spent
10665            // with RAM low, then we want to kill processes.
10666            boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
10667
10668            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
10669                ProcessRecord proc = mLruProcesses.get(i);
10670                if (proc.notCachedSinceIdle) {
10671                    if (proc.setProcState > ActivityManager.PROCESS_STATE_TOP
10672                            && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
10673                        if (doKilling && proc.initialIdlePss != 0
10674                                && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
10675                            proc.kill("idle maint (pss " + proc.lastPss
10676                                    + " from " + proc.initialIdlePss + ")", true);
10677                        }
10678                    }
10679                } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME) {
10680                    proc.notCachedSinceIdle = true;
10681                    proc.initialIdlePss = 0;
10682                    proc.nextPssTime = ProcessList.computeNextPssTime(proc.curProcState, true,
10683                            isSleeping(), now);
10684                }
10685            }
10686
10687            mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
10688            mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
10689        }
10690    }
10691
10692    private void retrieveSettings() {
10693        final ContentResolver resolver = mContext.getContentResolver();
10694        String debugApp = Settings.Global.getString(
10695            resolver, Settings.Global.DEBUG_APP);
10696        boolean waitForDebugger = Settings.Global.getInt(
10697            resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
10698        boolean alwaysFinishActivities = Settings.Global.getInt(
10699            resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
10700        boolean forceRtl = Settings.Global.getInt(
10701                resolver, Settings.Global.DEVELOPMENT_FORCE_RTL, 0) != 0;
10702        // Transfer any global setting for forcing RTL layout, into a System Property
10703        SystemProperties.set(Settings.Global.DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
10704
10705        Configuration configuration = new Configuration();
10706        Settings.System.getConfiguration(resolver, configuration);
10707        if (forceRtl) {
10708            // This will take care of setting the correct layout direction flags
10709            configuration.setLayoutDirection(configuration.locale);
10710        }
10711
10712        synchronized (this) {
10713            mDebugApp = mOrigDebugApp = debugApp;
10714            mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
10715            mAlwaysFinishActivities = alwaysFinishActivities;
10716            // This happens before any activities are started, so we can
10717            // change mConfiguration in-place.
10718            updateConfigurationLocked(configuration, null, false, true);
10719            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
10720        }
10721    }
10722
10723    /** Loads resources after the current configuration has been set. */
10724    private void loadResourcesOnSystemReady() {
10725        final Resources res = mContext.getResources();
10726        mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
10727        mThumbnailWidth = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
10728        mThumbnailHeight = res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
10729    }
10730
10731    public boolean testIsSystemReady() {
10732        // no need to synchronize(this) just to read & return the value
10733        return mSystemReady;
10734    }
10735
10736    private static File getCalledPreBootReceiversFile() {
10737        File dataDir = Environment.getDataDirectory();
10738        File systemDir = new File(dataDir, "system");
10739        File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
10740        return fname;
10741    }
10742
10743    private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
10744        ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
10745        File file = getCalledPreBootReceiversFile();
10746        FileInputStream fis = null;
10747        try {
10748            fis = new FileInputStream(file);
10749            DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
10750            int fvers = dis.readInt();
10751            if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
10752                String vers = dis.readUTF();
10753                String codename = dis.readUTF();
10754                String build = dis.readUTF();
10755                if (android.os.Build.VERSION.RELEASE.equals(vers)
10756                        && android.os.Build.VERSION.CODENAME.equals(codename)
10757                        && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
10758                    int num = dis.readInt();
10759                    while (num > 0) {
10760                        num--;
10761                        String pkg = dis.readUTF();
10762                        String cls = dis.readUTF();
10763                        lastDoneReceivers.add(new ComponentName(pkg, cls));
10764                    }
10765                }
10766            }
10767        } catch (FileNotFoundException e) {
10768        } catch (IOException e) {
10769            Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
10770        } finally {
10771            if (fis != null) {
10772                try {
10773                    fis.close();
10774                } catch (IOException e) {
10775                }
10776            }
10777        }
10778        return lastDoneReceivers;
10779    }
10780
10781    private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
10782        File file = getCalledPreBootReceiversFile();
10783        FileOutputStream fos = null;
10784        DataOutputStream dos = null;
10785        try {
10786            fos = new FileOutputStream(file);
10787            dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
10788            dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
10789            dos.writeUTF(android.os.Build.VERSION.RELEASE);
10790            dos.writeUTF(android.os.Build.VERSION.CODENAME);
10791            dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
10792            dos.writeInt(list.size());
10793            for (int i=0; i<list.size(); i++) {
10794                dos.writeUTF(list.get(i).getPackageName());
10795                dos.writeUTF(list.get(i).getClassName());
10796            }
10797        } catch (IOException e) {
10798            Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
10799            file.delete();
10800        } finally {
10801            FileUtils.sync(fos);
10802            if (dos != null) {
10803                try {
10804                    dos.close();
10805                } catch (IOException e) {
10806                    // TODO Auto-generated catch block
10807                    e.printStackTrace();
10808                }
10809            }
10810        }
10811    }
10812
10813    private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
10814            ArrayList<ComponentName> doneReceivers, int userId) {
10815        boolean waitingUpdate = false;
10816        Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
10817        List<ResolveInfo> ris = null;
10818        try {
10819            ris = AppGlobals.getPackageManager().queryIntentReceivers(
10820                    intent, null, 0, userId);
10821        } catch (RemoteException e) {
10822        }
10823        if (ris != null) {
10824            for (int i=ris.size()-1; i>=0; i--) {
10825                if ((ris.get(i).activityInfo.applicationInfo.flags
10826                        &ApplicationInfo.FLAG_SYSTEM) == 0) {
10827                    ris.remove(i);
10828                }
10829            }
10830            intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
10831
10832            // For User 0, load the version number. When delivering to a new user, deliver
10833            // to all receivers.
10834            if (userId == UserHandle.USER_OWNER) {
10835                ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
10836                for (int i=0; i<ris.size(); i++) {
10837                    ActivityInfo ai = ris.get(i).activityInfo;
10838                    ComponentName comp = new ComponentName(ai.packageName, ai.name);
10839                    if (lastDoneReceivers.contains(comp)) {
10840                        // We already did the pre boot receiver for this app with the current
10841                        // platform version, so don't do it again...
10842                        ris.remove(i);
10843                        i--;
10844                        // ...however, do keep it as one that has been done, so we don't
10845                        // forget about it when rewriting the file of last done receivers.
10846                        doneReceivers.add(comp);
10847                    }
10848                }
10849            }
10850
10851            // If primary user, send broadcast to all available users, else just to userId
10852            final int[] users = userId == UserHandle.USER_OWNER ? getUsersLocked()
10853                    : new int[] { userId };
10854            for (int i = 0; i < ris.size(); i++) {
10855                ActivityInfo ai = ris.get(i).activityInfo;
10856                ComponentName comp = new ComponentName(ai.packageName, ai.name);
10857                doneReceivers.add(comp);
10858                intent.setComponent(comp);
10859                for (int j=0; j<users.length; j++) {
10860                    IIntentReceiver finisher = null;
10861                    // On last receiver and user, set up a completion callback
10862                    if (i == ris.size() - 1 && j == users.length - 1 && onFinishCallback != null) {
10863                        finisher = new IIntentReceiver.Stub() {
10864                            public void performReceive(Intent intent, int resultCode,
10865                                    String data, Bundle extras, boolean ordered,
10866                                    boolean sticky, int sendingUser) {
10867                                // The raw IIntentReceiver interface is called
10868                                // with the AM lock held, so redispatch to
10869                                // execute our code without the lock.
10870                                mHandler.post(onFinishCallback);
10871                            }
10872                        };
10873                    }
10874                    Slog.i(TAG, "Sending system update to " + intent.getComponent()
10875                            + " for user " + users[j]);
10876                    broadcastIntentLocked(null, null, intent, null, finisher,
10877                            0, null, null, null, AppOpsManager.OP_NONE,
10878                            true, false, MY_PID, Process.SYSTEM_UID,
10879                            users[j]);
10880                    if (finisher != null) {
10881                        waitingUpdate = true;
10882                    }
10883                }
10884            }
10885        }
10886
10887        return waitingUpdate;
10888    }
10889
10890    public void systemReady(final Runnable goingCallback) {
10891        synchronized(this) {
10892            if (mSystemReady) {
10893                // If we're done calling all the receivers, run the next "boot phase" passed in
10894                // by the SystemServer
10895                if (goingCallback != null) {
10896                    goingCallback.run();
10897                }
10898                return;
10899            }
10900
10901            // Make sure we have the current profile info, since it is needed for
10902            // security checks.
10903            updateCurrentProfileIdsLocked();
10904
10905            if (mRecentTasks == null) {
10906                mRecentTasks = mTaskPersister.restoreTasksLocked();
10907                if (!mRecentTasks.isEmpty()) {
10908                    mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
10909                }
10910                cleanupRecentTasksLocked(UserHandle.USER_ALL);
10911                mTaskPersister.startPersisting();
10912            }
10913
10914            // Check to see if there are any update receivers to run.
10915            if (!mDidUpdate) {
10916                if (mWaitingUpdate) {
10917                    return;
10918                }
10919                final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
10920                mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
10921                    public void run() {
10922                        synchronized (ActivityManagerService.this) {
10923                            mDidUpdate = true;
10924                        }
10925                        writeLastDonePreBootReceivers(doneReceivers);
10926                        showBootMessage(mContext.getText(
10927                                R.string.android_upgrading_complete),
10928                                false);
10929                        systemReady(goingCallback);
10930                    }
10931                }, doneReceivers, UserHandle.USER_OWNER);
10932
10933                if (mWaitingUpdate) {
10934                    return;
10935                }
10936                mDidUpdate = true;
10937            }
10938
10939            mAppOpsService.systemReady();
10940            mSystemReady = true;
10941        }
10942
10943        ArrayList<ProcessRecord> procsToKill = null;
10944        synchronized(mPidsSelfLocked) {
10945            for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
10946                ProcessRecord proc = mPidsSelfLocked.valueAt(i);
10947                if (!isAllowedWhileBooting(proc.info)){
10948                    if (procsToKill == null) {
10949                        procsToKill = new ArrayList<ProcessRecord>();
10950                    }
10951                    procsToKill.add(proc);
10952                }
10953            }
10954        }
10955
10956        synchronized(this) {
10957            if (procsToKill != null) {
10958                for (int i=procsToKill.size()-1; i>=0; i--) {
10959                    ProcessRecord proc = procsToKill.get(i);
10960                    Slog.i(TAG, "Removing system update proc: " + proc);
10961                    removeProcessLocked(proc, true, false, "system update done");
10962                }
10963            }
10964
10965            // Now that we have cleaned up any update processes, we
10966            // are ready to start launching real processes and know that
10967            // we won't trample on them any more.
10968            mProcessesReady = true;
10969        }
10970
10971        Slog.i(TAG, "System now ready");
10972        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
10973            SystemClock.uptimeMillis());
10974
10975        synchronized(this) {
10976            // Make sure we have no pre-ready processes sitting around.
10977
10978            if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
10979                ResolveInfo ri = mContext.getPackageManager()
10980                        .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
10981                                STOCK_PM_FLAGS);
10982                CharSequence errorMsg = null;
10983                if (ri != null) {
10984                    ActivityInfo ai = ri.activityInfo;
10985                    ApplicationInfo app = ai.applicationInfo;
10986                    if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
10987                        mTopAction = Intent.ACTION_FACTORY_TEST;
10988                        mTopData = null;
10989                        mTopComponent = new ComponentName(app.packageName,
10990                                ai.name);
10991                    } else {
10992                        errorMsg = mContext.getResources().getText(
10993                                com.android.internal.R.string.factorytest_not_system);
10994                    }
10995                } else {
10996                    errorMsg = mContext.getResources().getText(
10997                            com.android.internal.R.string.factorytest_no_action);
10998                }
10999                if (errorMsg != null) {
11000                    mTopAction = null;
11001                    mTopData = null;
11002                    mTopComponent = null;
11003                    Message msg = Message.obtain();
11004                    msg.what = SHOW_FACTORY_ERROR_MSG;
11005                    msg.getData().putCharSequence("msg", errorMsg);
11006                    mHandler.sendMessage(msg);
11007                }
11008            }
11009        }
11010
11011        retrieveSettings();
11012        loadResourcesOnSystemReady();
11013
11014        synchronized (this) {
11015            readGrantedUriPermissionsLocked();
11016        }
11017
11018        if (goingCallback != null) goingCallback.run();
11019
11020        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
11021                Integer.toString(mCurrentUserId), mCurrentUserId);
11022        mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
11023                Integer.toString(mCurrentUserId), mCurrentUserId);
11024        mSystemServiceManager.startUser(mCurrentUserId);
11025
11026        synchronized (this) {
11027            if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
11028                try {
11029                    List apps = AppGlobals.getPackageManager().
11030                        getPersistentApplications(STOCK_PM_FLAGS);
11031                    if (apps != null) {
11032                        int N = apps.size();
11033                        int i;
11034                        for (i=0; i<N; i++) {
11035                            ApplicationInfo info
11036                                = (ApplicationInfo)apps.get(i);
11037                            if (info != null &&
11038                                    !info.packageName.equals("android")) {
11039                                addAppLocked(info, false, null /* ABI override */);
11040                            }
11041                        }
11042                    }
11043                } catch (RemoteException ex) {
11044                    // pm is in same process, this will never happen.
11045                }
11046            }
11047
11048            // Start up initial activity.
11049            mBooting = true;
11050
11051            try {
11052                if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
11053                    Message msg = Message.obtain();
11054                    msg.what = SHOW_UID_ERROR_MSG;
11055                    mHandler.sendMessage(msg);
11056                }
11057            } catch (RemoteException e) {
11058            }
11059
11060            long ident = Binder.clearCallingIdentity();
11061            try {
11062                Intent intent = new Intent(Intent.ACTION_USER_STARTED);
11063                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
11064                        | Intent.FLAG_RECEIVER_FOREGROUND);
11065                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11066                broadcastIntentLocked(null, null, intent,
11067                        null, null, 0, null, null, null, AppOpsManager.OP_NONE,
11068                        false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
11069                intent = new Intent(Intent.ACTION_USER_STARTING);
11070                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11071                intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
11072                broadcastIntentLocked(null, null, intent,
11073                        null, new IIntentReceiver.Stub() {
11074                            @Override
11075                            public void performReceive(Intent intent, int resultCode, String data,
11076                                    Bundle extras, boolean ordered, boolean sticky, int sendingUser)
11077                                    throws RemoteException {
11078                            }
11079                        }, 0, null, null,
11080                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
11081                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
11082            } catch (Throwable t) {
11083                Slog.wtf(TAG, "Failed sending first user broadcasts", t);
11084            } finally {
11085                Binder.restoreCallingIdentity(ident);
11086            }
11087            mStackSupervisor.resumeTopActivitiesLocked();
11088            sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
11089        }
11090    }
11091
11092    private boolean makeAppCrashingLocked(ProcessRecord app,
11093            String shortMsg, String longMsg, String stackTrace) {
11094        app.crashing = true;
11095        app.crashingReport = generateProcessError(app,
11096                ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
11097        startAppProblemLocked(app);
11098        app.stopFreezingAllLocked();
11099        return handleAppCrashLocked(app, shortMsg, longMsg, stackTrace);
11100    }
11101
11102    private void makeAppNotRespondingLocked(ProcessRecord app,
11103            String activity, String shortMsg, String longMsg) {
11104        app.notResponding = true;
11105        app.notRespondingReport = generateProcessError(app,
11106                ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
11107                activity, shortMsg, longMsg, null);
11108        startAppProblemLocked(app);
11109        app.stopFreezingAllLocked();
11110    }
11111
11112    /**
11113     * Generate a process error record, suitable for attachment to a ProcessRecord.
11114     *
11115     * @param app The ProcessRecord in which the error occurred.
11116     * @param condition Crashing, Application Not Responding, etc.  Values are defined in
11117     *                      ActivityManager.AppErrorStateInfo
11118     * @param activity The activity associated with the crash, if known.
11119     * @param shortMsg Short message describing the crash.
11120     * @param longMsg Long message describing the crash.
11121     * @param stackTrace Full crash stack trace, may be null.
11122     *
11123     * @return Returns a fully-formed AppErrorStateInfo record.
11124     */
11125    private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
11126            int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
11127        ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
11128
11129        report.condition = condition;
11130        report.processName = app.processName;
11131        report.pid = app.pid;
11132        report.uid = app.info.uid;
11133        report.tag = activity;
11134        report.shortMsg = shortMsg;
11135        report.longMsg = longMsg;
11136        report.stackTrace = stackTrace;
11137
11138        return report;
11139    }
11140
11141    void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
11142        synchronized (this) {
11143            app.crashing = false;
11144            app.crashingReport = null;
11145            app.notResponding = false;
11146            app.notRespondingReport = null;
11147            if (app.anrDialog == fromDialog) {
11148                app.anrDialog = null;
11149            }
11150            if (app.waitDialog == fromDialog) {
11151                app.waitDialog = null;
11152            }
11153            if (app.pid > 0 && app.pid != MY_PID) {
11154                handleAppCrashLocked(app, null, null, null);
11155                app.kill("user request after error", true);
11156            }
11157        }
11158    }
11159
11160    private boolean handleAppCrashLocked(ProcessRecord app, String shortMsg, String longMsg,
11161            String stackTrace) {
11162        long now = SystemClock.uptimeMillis();
11163
11164        Long crashTime;
11165        if (!app.isolated) {
11166            crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
11167        } else {
11168            crashTime = null;
11169        }
11170        if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
11171            // This process loses!
11172            Slog.w(TAG, "Process " + app.info.processName
11173                    + " has crashed too many times: killing!");
11174            EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
11175                    app.userId, app.info.processName, app.uid);
11176            mStackSupervisor.handleAppCrashLocked(app);
11177            if (!app.persistent) {
11178                // We don't want to start this process again until the user
11179                // explicitly does so...  but for persistent process, we really
11180                // need to keep it running.  If a persistent process is actually
11181                // repeatedly crashing, then badness for everyone.
11182                EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
11183                        app.info.processName);
11184                if (!app.isolated) {
11185                    // XXX We don't have a way to mark isolated processes
11186                    // as bad, since they don't have a peristent identity.
11187                    mBadProcesses.put(app.info.processName, app.uid,
11188                            new BadProcessInfo(now, shortMsg, longMsg, stackTrace));
11189                    mProcessCrashTimes.remove(app.info.processName, app.uid);
11190                }
11191                app.bad = true;
11192                app.removed = true;
11193                // Don't let services in this process be restarted and potentially
11194                // annoy the user repeatedly.  Unless it is persistent, since those
11195                // processes run critical code.
11196                removeProcessLocked(app, false, false, "crash");
11197                mStackSupervisor.resumeTopActivitiesLocked();
11198                return false;
11199            }
11200            mStackSupervisor.resumeTopActivitiesLocked();
11201        } else {
11202            mStackSupervisor.finishTopRunningActivityLocked(app);
11203        }
11204
11205        // Bump up the crash count of any services currently running in the proc.
11206        for (int i=app.services.size()-1; i>=0; i--) {
11207            // Any services running in the application need to be placed
11208            // back in the pending list.
11209            ServiceRecord sr = app.services.valueAt(i);
11210            sr.crashCount++;
11211        }
11212
11213        // If the crashing process is what we consider to be the "home process" and it has been
11214        // replaced by a third-party app, clear the package preferred activities from packages
11215        // with a home activity running in the process to prevent a repeatedly crashing app
11216        // from blocking the user to manually clear the list.
11217        final ArrayList<ActivityRecord> activities = app.activities;
11218        if (app == mHomeProcess && activities.size() > 0
11219                    && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
11220            for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
11221                final ActivityRecord r = activities.get(activityNdx);
11222                if (r.isHomeActivity()) {
11223                    Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
11224                    try {
11225                        ActivityThread.getPackageManager()
11226                                .clearPackagePreferredActivities(r.packageName);
11227                    } catch (RemoteException c) {
11228                        // pm is in same process, this will never happen.
11229                    }
11230                }
11231            }
11232        }
11233
11234        if (!app.isolated) {
11235            // XXX Can't keep track of crash times for isolated processes,
11236            // because they don't have a perisistent identity.
11237            mProcessCrashTimes.put(app.info.processName, app.uid, now);
11238        }
11239
11240        if (app.crashHandler != null) mHandler.post(app.crashHandler);
11241        return true;
11242    }
11243
11244    void startAppProblemLocked(ProcessRecord app) {
11245        // If this app is not running under the current user, then we
11246        // can't give it a report button because that would require
11247        // launching the report UI under a different user.
11248        app.errorReportReceiver = null;
11249
11250        for (int userId : mCurrentProfileIds) {
11251            if (app.userId == userId) {
11252                app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
11253                        mContext, app.info.packageName, app.info.flags);
11254            }
11255        }
11256        skipCurrentReceiverLocked(app);
11257    }
11258
11259    void skipCurrentReceiverLocked(ProcessRecord app) {
11260        for (BroadcastQueue queue : mBroadcastQueues) {
11261            queue.skipCurrentReceiverLocked(app);
11262        }
11263    }
11264
11265    /**
11266     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
11267     * The application process will exit immediately after this call returns.
11268     * @param app object of the crashing app, null for the system server
11269     * @param crashInfo describing the exception
11270     */
11271    public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
11272        ProcessRecord r = findAppProcess(app, "Crash");
11273        final String processName = app == null ? "system_server"
11274                : (r == null ? "unknown" : r.processName);
11275
11276        handleApplicationCrashInner("crash", r, processName, crashInfo);
11277    }
11278
11279    /* Native crash reporting uses this inner version because it needs to be somewhat
11280     * decoupled from the AM-managed cleanup lifecycle
11281     */
11282    void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
11283            ApplicationErrorReport.CrashInfo crashInfo) {
11284        EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
11285                UserHandle.getUserId(Binder.getCallingUid()), processName,
11286                r == null ? -1 : r.info.flags,
11287                crashInfo.exceptionClassName,
11288                crashInfo.exceptionMessage,
11289                crashInfo.throwFileName,
11290                crashInfo.throwLineNumber);
11291
11292        addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
11293
11294        crashApplication(r, crashInfo);
11295    }
11296
11297    public void handleApplicationStrictModeViolation(
11298            IBinder app,
11299            int violationMask,
11300            StrictMode.ViolationInfo info) {
11301        ProcessRecord r = findAppProcess(app, "StrictMode");
11302        if (r == null) {
11303            return;
11304        }
11305
11306        if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
11307            Integer stackFingerprint = info.hashCode();
11308            boolean logIt = true;
11309            synchronized (mAlreadyLoggedViolatedStacks) {
11310                if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
11311                    logIt = false;
11312                    // TODO: sub-sample into EventLog for these, with
11313                    // the info.durationMillis?  Then we'd get
11314                    // the relative pain numbers, without logging all
11315                    // the stack traces repeatedly.  We'd want to do
11316                    // likewise in the client code, which also does
11317                    // dup suppression, before the Binder call.
11318                } else {
11319                    if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
11320                        mAlreadyLoggedViolatedStacks.clear();
11321                    }
11322                    mAlreadyLoggedViolatedStacks.add(stackFingerprint);
11323                }
11324            }
11325            if (logIt) {
11326                logStrictModeViolationToDropBox(r, info);
11327            }
11328        }
11329
11330        if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
11331            AppErrorResult result = new AppErrorResult();
11332            synchronized (this) {
11333                final long origId = Binder.clearCallingIdentity();
11334
11335                Message msg = Message.obtain();
11336                msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
11337                HashMap<String, Object> data = new HashMap<String, Object>();
11338                data.put("result", result);
11339                data.put("app", r);
11340                data.put("violationMask", violationMask);
11341                data.put("info", info);
11342                msg.obj = data;
11343                mHandler.sendMessage(msg);
11344
11345                Binder.restoreCallingIdentity(origId);
11346            }
11347            int res = result.get();
11348            Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
11349        }
11350    }
11351
11352    // Depending on the policy in effect, there could be a bunch of
11353    // these in quick succession so we try to batch these together to
11354    // minimize disk writes, number of dropbox entries, and maximize
11355    // compression, by having more fewer, larger records.
11356    private void logStrictModeViolationToDropBox(
11357            ProcessRecord process,
11358            StrictMode.ViolationInfo info) {
11359        if (info == null) {
11360            return;
11361        }
11362        final boolean isSystemApp = process == null ||
11363                (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
11364                                       ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
11365        final String processName = process == null ? "unknown" : process.processName;
11366        final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
11367        final DropBoxManager dbox = (DropBoxManager)
11368                mContext.getSystemService(Context.DROPBOX_SERVICE);
11369
11370        // Exit early if the dropbox isn't configured to accept this report type.
11371        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11372
11373        boolean bufferWasEmpty;
11374        boolean needsFlush;
11375        final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
11376        synchronized (sb) {
11377            bufferWasEmpty = sb.length() == 0;
11378            appendDropBoxProcessHeaders(process, processName, sb);
11379            sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11380            sb.append("System-App: ").append(isSystemApp).append("\n");
11381            sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
11382            if (info.violationNumThisLoop != 0) {
11383                sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
11384            }
11385            if (info.numAnimationsRunning != 0) {
11386                sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
11387            }
11388            if (info.broadcastIntentAction != null) {
11389                sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
11390            }
11391            if (info.durationMillis != -1) {
11392                sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
11393            }
11394            if (info.numInstances != -1) {
11395                sb.append("Instance-Count: ").append(info.numInstances).append("\n");
11396            }
11397            if (info.tags != null) {
11398                for (String tag : info.tags) {
11399                    sb.append("Span-Tag: ").append(tag).append("\n");
11400                }
11401            }
11402            sb.append("\n");
11403            if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
11404                sb.append(info.crashInfo.stackTrace);
11405            }
11406            sb.append("\n");
11407
11408            // Only buffer up to ~64k.  Various logging bits truncate
11409            // things at 128k.
11410            needsFlush = (sb.length() > 64 * 1024);
11411        }
11412
11413        // Flush immediately if the buffer's grown too large, or this
11414        // is a non-system app.  Non-system apps are isolated with a
11415        // different tag & policy and not batched.
11416        //
11417        // Batching is useful during internal testing with
11418        // StrictMode settings turned up high.  Without batching,
11419        // thousands of separate files could be created on boot.
11420        if (!isSystemApp || needsFlush) {
11421            new Thread("Error dump: " + dropboxTag) {
11422                @Override
11423                public void run() {
11424                    String report;
11425                    synchronized (sb) {
11426                        report = sb.toString();
11427                        sb.delete(0, sb.length());
11428                        sb.trimToSize();
11429                    }
11430                    if (report.length() != 0) {
11431                        dbox.addText(dropboxTag, report);
11432                    }
11433                }
11434            }.start();
11435            return;
11436        }
11437
11438        // System app batching:
11439        if (!bufferWasEmpty) {
11440            // An existing dropbox-writing thread is outstanding, so
11441            // we don't need to start it up.  The existing thread will
11442            // catch the buffer appends we just did.
11443            return;
11444        }
11445
11446        // Worker thread to both batch writes and to avoid blocking the caller on I/O.
11447        // (After this point, we shouldn't access AMS internal data structures.)
11448        new Thread("Error dump: " + dropboxTag) {
11449            @Override
11450            public void run() {
11451                // 5 second sleep to let stacks arrive and be batched together
11452                try {
11453                    Thread.sleep(5000);  // 5 seconds
11454                } catch (InterruptedException e) {}
11455
11456                String errorReport;
11457                synchronized (mStrictModeBuffer) {
11458                    errorReport = mStrictModeBuffer.toString();
11459                    if (errorReport.length() == 0) {
11460                        return;
11461                    }
11462                    mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
11463                    mStrictModeBuffer.trimToSize();
11464                }
11465                dbox.addText(dropboxTag, errorReport);
11466            }
11467        }.start();
11468    }
11469
11470    /**
11471     * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
11472     * @param app object of the crashing app, null for the system server
11473     * @param tag reported by the caller
11474     * @param system whether this wtf is coming from the system
11475     * @param crashInfo describing the context of the error
11476     * @return true if the process should exit immediately (WTF is fatal)
11477     */
11478    public boolean handleApplicationWtf(IBinder app, final String tag, boolean system,
11479            final ApplicationErrorReport.CrashInfo crashInfo) {
11480        final ProcessRecord r = findAppProcess(app, "WTF");
11481        final String processName = app == null ? "system_server"
11482                : (r == null ? "unknown" : r.processName);
11483
11484        EventLog.writeEvent(EventLogTags.AM_WTF,
11485                UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
11486                processName,
11487                r == null ? -1 : r.info.flags,
11488                tag, crashInfo.exceptionMessage);
11489
11490        if (system) {
11491            // If this is coming from the system, we could very well have low-level
11492            // system locks held, so we want to do this all asynchronously.  And we
11493            // never want this to become fatal, so there is that too.
11494            mHandler.post(new Runnable() {
11495                @Override public void run() {
11496                    addErrorToDropBox("wtf", r, processName, null, null, tag, null, null,
11497                            crashInfo);
11498                }
11499            });
11500            return false;
11501        }
11502
11503        addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
11504
11505        if (r != null && r.pid != Process.myPid() &&
11506                Settings.Global.getInt(mContext.getContentResolver(),
11507                        Settings.Global.WTF_IS_FATAL, 0) != 0) {
11508            crashApplication(r, crashInfo);
11509            return true;
11510        } else {
11511            return false;
11512        }
11513    }
11514
11515    /**
11516     * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
11517     * @return the corresponding {@link ProcessRecord} object, or null if none could be found
11518     */
11519    private ProcessRecord findAppProcess(IBinder app, String reason) {
11520        if (app == null) {
11521            return null;
11522        }
11523
11524        synchronized (this) {
11525            final int NP = mProcessNames.getMap().size();
11526            for (int ip=0; ip<NP; ip++) {
11527                SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11528                final int NA = apps.size();
11529                for (int ia=0; ia<NA; ia++) {
11530                    ProcessRecord p = apps.valueAt(ia);
11531                    if (p.thread != null && p.thread.asBinder() == app) {
11532                        return p;
11533                    }
11534                }
11535            }
11536
11537            Slog.w(TAG, "Can't find mystery application for " + reason
11538                    + " from pid=" + Binder.getCallingPid()
11539                    + " uid=" + Binder.getCallingUid() + ": " + app);
11540            return null;
11541        }
11542    }
11543
11544    /**
11545     * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
11546     * to append various headers to the dropbox log text.
11547     */
11548    private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
11549            StringBuilder sb) {
11550        // Watchdog thread ends up invoking this function (with
11551        // a null ProcessRecord) to add the stack file to dropbox.
11552        // Do not acquire a lock on this (am) in such cases, as it
11553        // could cause a potential deadlock, if and when watchdog
11554        // is invoked due to unavailability of lock on am and it
11555        // would prevent watchdog from killing system_server.
11556        if (process == null) {
11557            sb.append("Process: ").append(processName).append("\n");
11558            return;
11559        }
11560        // Note: ProcessRecord 'process' is guarded by the service
11561        // instance.  (notably process.pkgList, which could otherwise change
11562        // concurrently during execution of this method)
11563        synchronized (this) {
11564            sb.append("Process: ").append(processName).append("\n");
11565            int flags = process.info.flags;
11566            IPackageManager pm = AppGlobals.getPackageManager();
11567            sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
11568            for (int ip=0; ip<process.pkgList.size(); ip++) {
11569                String pkg = process.pkgList.keyAt(ip);
11570                sb.append("Package: ").append(pkg);
11571                try {
11572                    PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
11573                    if (pi != null) {
11574                        sb.append(" v").append(pi.versionCode);
11575                        if (pi.versionName != null) {
11576                            sb.append(" (").append(pi.versionName).append(")");
11577                        }
11578                    }
11579                } catch (RemoteException e) {
11580                    Slog.e(TAG, "Error getting package info: " + pkg, e);
11581                }
11582                sb.append("\n");
11583            }
11584        }
11585    }
11586
11587    private static String processClass(ProcessRecord process) {
11588        if (process == null || process.pid == MY_PID) {
11589            return "system_server";
11590        } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
11591            return "system_app";
11592        } else {
11593            return "data_app";
11594        }
11595    }
11596
11597    /**
11598     * Write a description of an error (crash, WTF, ANR) to the drop box.
11599     * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
11600     * @param process which caused the error, null means the system server
11601     * @param activity which triggered the error, null if unknown
11602     * @param parent activity related to the error, null if unknown
11603     * @param subject line related to the error, null if absent
11604     * @param report in long form describing the error, null if absent
11605     * @param logFile to include in the report, null if none
11606     * @param crashInfo giving an application stack trace, null if absent
11607     */
11608    public void addErrorToDropBox(String eventType,
11609            ProcessRecord process, String processName, ActivityRecord activity,
11610            ActivityRecord parent, String subject,
11611            final String report, final File logFile,
11612            final ApplicationErrorReport.CrashInfo crashInfo) {
11613        // NOTE -- this must never acquire the ActivityManagerService lock,
11614        // otherwise the watchdog may be prevented from resetting the system.
11615
11616        final String dropboxTag = processClass(process) + "_" + eventType;
11617        final DropBoxManager dbox = (DropBoxManager)
11618                mContext.getSystemService(Context.DROPBOX_SERVICE);
11619
11620        // Exit early if the dropbox isn't configured to accept this report type.
11621        if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
11622
11623        final StringBuilder sb = new StringBuilder(1024);
11624        appendDropBoxProcessHeaders(process, processName, sb);
11625        if (activity != null) {
11626            sb.append("Activity: ").append(activity.shortComponentName).append("\n");
11627        }
11628        if (parent != null && parent.app != null && parent.app.pid != process.pid) {
11629            sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
11630        }
11631        if (parent != null && parent != activity) {
11632            sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
11633        }
11634        if (subject != null) {
11635            sb.append("Subject: ").append(subject).append("\n");
11636        }
11637        sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
11638        if (Debug.isDebuggerConnected()) {
11639            sb.append("Debugger: Connected\n");
11640        }
11641        sb.append("\n");
11642
11643        // Do the rest in a worker thread to avoid blocking the caller on I/O
11644        // (After this point, we shouldn't access AMS internal data structures.)
11645        Thread worker = new Thread("Error dump: " + dropboxTag) {
11646            @Override
11647            public void run() {
11648                if (report != null) {
11649                    sb.append(report);
11650                }
11651                if (logFile != null) {
11652                    try {
11653                        sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
11654                                    "\n\n[[TRUNCATED]]"));
11655                    } catch (IOException e) {
11656                        Slog.e(TAG, "Error reading " + logFile, e);
11657                    }
11658                }
11659                if (crashInfo != null && crashInfo.stackTrace != null) {
11660                    sb.append(crashInfo.stackTrace);
11661                }
11662
11663                String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
11664                int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
11665                if (lines > 0) {
11666                    sb.append("\n");
11667
11668                    // Merge several logcat streams, and take the last N lines
11669                    InputStreamReader input = null;
11670                    try {
11671                        java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
11672                                "-v", "time", "-b", "events", "-b", "system", "-b", "main",
11673                                "-b", "crash",
11674                                "-t", String.valueOf(lines)).redirectErrorStream(true).start();
11675
11676                        try { logcat.getOutputStream().close(); } catch (IOException e) {}
11677                        try { logcat.getErrorStream().close(); } catch (IOException e) {}
11678                        input = new InputStreamReader(logcat.getInputStream());
11679
11680                        int num;
11681                        char[] buf = new char[8192];
11682                        while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
11683                    } catch (IOException e) {
11684                        Slog.e(TAG, "Error running logcat", e);
11685                    } finally {
11686                        if (input != null) try { input.close(); } catch (IOException e) {}
11687                    }
11688                }
11689
11690                dbox.addText(dropboxTag, sb.toString());
11691            }
11692        };
11693
11694        if (process == null) {
11695            // If process is null, we are being called from some internal code
11696            // and may be about to die -- run this synchronously.
11697            worker.run();
11698        } else {
11699            worker.start();
11700        }
11701    }
11702
11703    /**
11704     * Bring up the "unexpected error" dialog box for a crashing app.
11705     * Deal with edge cases (intercepts from instrumented applications,
11706     * ActivityController, error intent receivers, that sort of thing).
11707     * @param r the application crashing
11708     * @param crashInfo describing the failure
11709     */
11710    private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
11711        long timeMillis = System.currentTimeMillis();
11712        String shortMsg = crashInfo.exceptionClassName;
11713        String longMsg = crashInfo.exceptionMessage;
11714        String stackTrace = crashInfo.stackTrace;
11715        if (shortMsg != null && longMsg != null) {
11716            longMsg = shortMsg + ": " + longMsg;
11717        } else if (shortMsg != null) {
11718            longMsg = shortMsg;
11719        }
11720
11721        AppErrorResult result = new AppErrorResult();
11722        synchronized (this) {
11723            if (mController != null) {
11724                try {
11725                    String name = r != null ? r.processName : null;
11726                    int pid = r != null ? r.pid : Binder.getCallingPid();
11727                    int uid = r != null ? r.info.uid : Binder.getCallingUid();
11728                    if (!mController.appCrashed(name, pid,
11729                            shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
11730                        if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
11731                                && "Native crash".equals(crashInfo.exceptionClassName)) {
11732                            Slog.w(TAG, "Skip killing native crashed app " + name
11733                                    + "(" + pid + ") during testing");
11734                        } else {
11735                            Slog.w(TAG, "Force-killing crashed app " + name
11736                                    + " at watcher's request");
11737                            if (r != null) {
11738                                r.kill("crash", true);
11739                            } else {
11740                                // Huh.
11741                                Process.killProcess(pid);
11742                                Process.killProcessGroup(uid, pid);
11743                            }
11744                        }
11745                        return;
11746                    }
11747                } catch (RemoteException e) {
11748                    mController = null;
11749                    Watchdog.getInstance().setActivityController(null);
11750                }
11751            }
11752
11753            final long origId = Binder.clearCallingIdentity();
11754
11755            // If this process is running instrumentation, finish it.
11756            if (r != null && r.instrumentationClass != null) {
11757                Slog.w(TAG, "Error in app " + r.processName
11758                      + " running instrumentation " + r.instrumentationClass + ":");
11759                if (shortMsg != null) Slog.w(TAG, "  " + shortMsg);
11760                if (longMsg != null) Slog.w(TAG, "  " + longMsg);
11761                Bundle info = new Bundle();
11762                info.putString("shortMsg", shortMsg);
11763                info.putString("longMsg", longMsg);
11764                finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
11765                Binder.restoreCallingIdentity(origId);
11766                return;
11767            }
11768
11769            // If we can't identify the process or it's already exceeded its crash quota,
11770            // quit right away without showing a crash dialog.
11771            if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
11772                Binder.restoreCallingIdentity(origId);
11773                return;
11774            }
11775
11776            Message msg = Message.obtain();
11777            msg.what = SHOW_ERROR_MSG;
11778            HashMap data = new HashMap();
11779            data.put("result", result);
11780            data.put("app", r);
11781            msg.obj = data;
11782            mHandler.sendMessage(msg);
11783
11784            Binder.restoreCallingIdentity(origId);
11785        }
11786
11787        int res = result.get();
11788
11789        Intent appErrorIntent = null;
11790        synchronized (this) {
11791            if (r != null && !r.isolated) {
11792                // XXX Can't keep track of crash time for isolated processes,
11793                // since they don't have a persistent identity.
11794                mProcessCrashTimes.put(r.info.processName, r.uid,
11795                        SystemClock.uptimeMillis());
11796            }
11797            if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
11798                appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
11799            }
11800        }
11801
11802        if (appErrorIntent != null) {
11803            try {
11804                mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
11805            } catch (ActivityNotFoundException e) {
11806                Slog.w(TAG, "bug report receiver dissappeared", e);
11807            }
11808        }
11809    }
11810
11811    Intent createAppErrorIntentLocked(ProcessRecord r,
11812            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11813        ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
11814        if (report == null) {
11815            return null;
11816        }
11817        Intent result = new Intent(Intent.ACTION_APP_ERROR);
11818        result.setComponent(r.errorReportReceiver);
11819        result.putExtra(Intent.EXTRA_BUG_REPORT, report);
11820        result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
11821        return result;
11822    }
11823
11824    private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
11825            long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
11826        if (r.errorReportReceiver == null) {
11827            return null;
11828        }
11829
11830        if (!r.crashing && !r.notResponding && !r.forceCrashReport) {
11831            return null;
11832        }
11833
11834        ApplicationErrorReport report = new ApplicationErrorReport();
11835        report.packageName = r.info.packageName;
11836        report.installerPackageName = r.errorReportReceiver.getPackageName();
11837        report.processName = r.processName;
11838        report.time = timeMillis;
11839        report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
11840
11841        if (r.crashing || r.forceCrashReport) {
11842            report.type = ApplicationErrorReport.TYPE_CRASH;
11843            report.crashInfo = crashInfo;
11844        } else if (r.notResponding) {
11845            report.type = ApplicationErrorReport.TYPE_ANR;
11846            report.anrInfo = new ApplicationErrorReport.AnrInfo();
11847
11848            report.anrInfo.activity = r.notRespondingReport.tag;
11849            report.anrInfo.cause = r.notRespondingReport.shortMsg;
11850            report.anrInfo.info = r.notRespondingReport.longMsg;
11851        }
11852
11853        return report;
11854    }
11855
11856    public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
11857        enforceNotIsolatedCaller("getProcessesInErrorState");
11858        // assume our apps are happy - lazy create the list
11859        List<ActivityManager.ProcessErrorStateInfo> errList = null;
11860
11861        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11862                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11863        int userId = UserHandle.getUserId(Binder.getCallingUid());
11864
11865        synchronized (this) {
11866
11867            // iterate across all processes
11868            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11869                ProcessRecord app = mLruProcesses.get(i);
11870                if (!allUsers && app.userId != userId) {
11871                    continue;
11872                }
11873                if ((app.thread != null) && (app.crashing || app.notResponding)) {
11874                    // This one's in trouble, so we'll generate a report for it
11875                    // crashes are higher priority (in case there's a crash *and* an anr)
11876                    ActivityManager.ProcessErrorStateInfo report = null;
11877                    if (app.crashing) {
11878                        report = app.crashingReport;
11879                    } else if (app.notResponding) {
11880                        report = app.notRespondingReport;
11881                    }
11882
11883                    if (report != null) {
11884                        if (errList == null) {
11885                            errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
11886                        }
11887                        errList.add(report);
11888                    } else {
11889                        Slog.w(TAG, "Missing app error report, app = " + app.processName +
11890                                " crashing = " + app.crashing +
11891                                " notResponding = " + app.notResponding);
11892                    }
11893                }
11894            }
11895        }
11896
11897        return errList;
11898    }
11899
11900    static int procStateToImportance(int procState, int memAdj,
11901            ActivityManager.RunningAppProcessInfo currApp) {
11902        int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
11903        if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
11904            currApp.lru = memAdj;
11905        } else {
11906            currApp.lru = 0;
11907        }
11908        return imp;
11909    }
11910
11911    private void fillInProcMemInfo(ProcessRecord app,
11912            ActivityManager.RunningAppProcessInfo outInfo) {
11913        outInfo.pid = app.pid;
11914        outInfo.uid = app.info.uid;
11915        if (mHeavyWeightProcess == app) {
11916            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
11917        }
11918        if (app.persistent) {
11919            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
11920        }
11921        if (app.activities.size() > 0) {
11922            outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
11923        }
11924        outInfo.lastTrimLevel = app.trimMemoryLevel;
11925        int adj = app.curAdj;
11926        int procState = app.curProcState;
11927        outInfo.importance = procStateToImportance(procState, adj, outInfo);
11928        outInfo.importanceReasonCode = app.adjTypeCode;
11929        outInfo.processState = app.curProcState;
11930    }
11931
11932    public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
11933        enforceNotIsolatedCaller("getRunningAppProcesses");
11934        // Lazy instantiation of list
11935        List<ActivityManager.RunningAppProcessInfo> runList = null;
11936        final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
11937                Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
11938        int userId = UserHandle.getUserId(Binder.getCallingUid());
11939        synchronized (this) {
11940            // Iterate across all processes
11941            for (int i=mLruProcesses.size()-1; i>=0; i--) {
11942                ProcessRecord app = mLruProcesses.get(i);
11943                if (!allUsers && app.userId != userId) {
11944                    continue;
11945                }
11946                if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
11947                    // Generate process state info for running application
11948                    ActivityManager.RunningAppProcessInfo currApp =
11949                        new ActivityManager.RunningAppProcessInfo(app.processName,
11950                                app.pid, app.getPackageList());
11951                    fillInProcMemInfo(app, currApp);
11952                    if (app.adjSource instanceof ProcessRecord) {
11953                        currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
11954                        currApp.importanceReasonImportance =
11955                                ActivityManager.RunningAppProcessInfo.procStateToImportance(
11956                                        app.adjSourceProcState);
11957                    } else if (app.adjSource instanceof ActivityRecord) {
11958                        ActivityRecord r = (ActivityRecord)app.adjSource;
11959                        if (r.app != null) currApp.importanceReasonPid = r.app.pid;
11960                    }
11961                    if (app.adjTarget instanceof ComponentName) {
11962                        currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
11963                    }
11964                    //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
11965                    //        + " lru=" + currApp.lru);
11966                    if (runList == null) {
11967                        runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
11968                    }
11969                    runList.add(currApp);
11970                }
11971            }
11972        }
11973        return runList;
11974    }
11975
11976    public List<ApplicationInfo> getRunningExternalApplications() {
11977        enforceNotIsolatedCaller("getRunningExternalApplications");
11978        List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
11979        List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
11980        if (runningApps != null && runningApps.size() > 0) {
11981            Set<String> extList = new HashSet<String>();
11982            for (ActivityManager.RunningAppProcessInfo app : runningApps) {
11983                if (app.pkgList != null) {
11984                    for (String pkg : app.pkgList) {
11985                        extList.add(pkg);
11986                    }
11987                }
11988            }
11989            IPackageManager pm = AppGlobals.getPackageManager();
11990            for (String pkg : extList) {
11991                try {
11992                    ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
11993                    if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
11994                        retList.add(info);
11995                    }
11996                } catch (RemoteException e) {
11997                }
11998            }
11999        }
12000        return retList;
12001    }
12002
12003    @Override
12004    public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
12005        enforceNotIsolatedCaller("getMyMemoryState");
12006        synchronized (this) {
12007            ProcessRecord proc;
12008            synchronized (mPidsSelfLocked) {
12009                proc = mPidsSelfLocked.get(Binder.getCallingPid());
12010            }
12011            fillInProcMemInfo(proc, outInfo);
12012        }
12013    }
12014
12015    @Override
12016    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
12017        if (checkCallingPermission(android.Manifest.permission.DUMP)
12018                != PackageManager.PERMISSION_GRANTED) {
12019            pw.println("Permission Denial: can't dump ActivityManager from from pid="
12020                    + Binder.getCallingPid()
12021                    + ", uid=" + Binder.getCallingUid()
12022                    + " without permission "
12023                    + android.Manifest.permission.DUMP);
12024            return;
12025        }
12026
12027        boolean dumpAll = false;
12028        boolean dumpClient = false;
12029        String dumpPackage = null;
12030
12031        int opti = 0;
12032        while (opti < args.length) {
12033            String opt = args[opti];
12034            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
12035                break;
12036            }
12037            opti++;
12038            if ("-a".equals(opt)) {
12039                dumpAll = true;
12040            } else if ("-c".equals(opt)) {
12041                dumpClient = true;
12042            } else if ("-h".equals(opt)) {
12043                pw.println("Activity manager dump options:");
12044                pw.println("  [-a] [-c] [-h] [cmd] ...");
12045                pw.println("  cmd may be one of:");
12046                pw.println("    a[ctivities]: activity stack state");
12047                pw.println("    r[recents]: recent activities state");
12048                pw.println("    b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
12049                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
12050                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
12051                pw.println("    o[om]: out of memory management");
12052                pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
12053                pw.println("    provider [COMP_SPEC]: provider client-side state");
12054                pw.println("    s[ervices] [COMP_SPEC ...]: service state");
12055                pw.println("    service [COMP_SPEC]: service client-side state");
12056                pw.println("    package [PACKAGE_NAME]: all state related to given package");
12057                pw.println("    all: dump all activities");
12058                pw.println("    top: dump the top activity");
12059                pw.println("  cmd may also be a COMP_SPEC to dump activities.");
12060                pw.println("  COMP_SPEC may be a component name (com.foo/.myApp),");
12061                pw.println("    a partial substring in a component name, a");
12062                pw.println("    hex object identifier.");
12063                pw.println("  -a: include all available server state.");
12064                pw.println("  -c: include client state.");
12065                return;
12066            } else {
12067                pw.println("Unknown argument: " + opt + "; use -h for help");
12068            }
12069        }
12070
12071        long origId = Binder.clearCallingIdentity();
12072        boolean more = false;
12073        // Is the caller requesting to dump a particular piece of data?
12074        if (opti < args.length) {
12075            String cmd = args[opti];
12076            opti++;
12077            if ("activities".equals(cmd) || "a".equals(cmd)) {
12078                synchronized (this) {
12079                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
12080                }
12081            } else if ("recents".equals(cmd) || "r".equals(cmd)) {
12082                synchronized (this) {
12083                    dumpRecentsLocked(fd, pw, args, opti, true, null);
12084                }
12085            } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
12086                String[] newArgs;
12087                String name;
12088                if (opti >= args.length) {
12089                    name = null;
12090                    newArgs = EMPTY_STRING_ARRAY;
12091                } else {
12092                    name = args[opti];
12093                    opti++;
12094                    newArgs = new String[args.length - opti];
12095                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12096                            args.length - opti);
12097                }
12098                synchronized (this) {
12099                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
12100                }
12101            } else if ("intents".equals(cmd) || "i".equals(cmd)) {
12102                String[] newArgs;
12103                String name;
12104                if (opti >= args.length) {
12105                    name = null;
12106                    newArgs = EMPTY_STRING_ARRAY;
12107                } else {
12108                    name = args[opti];
12109                    opti++;
12110                    newArgs = new String[args.length - opti];
12111                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12112                            args.length - opti);
12113                }
12114                synchronized (this) {
12115                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
12116                }
12117            } else if ("processes".equals(cmd) || "p".equals(cmd)) {
12118                String[] newArgs;
12119                String name;
12120                if (opti >= args.length) {
12121                    name = null;
12122                    newArgs = EMPTY_STRING_ARRAY;
12123                } else {
12124                    name = args[opti];
12125                    opti++;
12126                    newArgs = new String[args.length - opti];
12127                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12128                            args.length - opti);
12129                }
12130                synchronized (this) {
12131                    dumpProcessesLocked(fd, pw, args, opti, true, name);
12132                }
12133            } else if ("oom".equals(cmd) || "o".equals(cmd)) {
12134                synchronized (this) {
12135                    dumpOomLocked(fd, pw, args, opti, true);
12136                }
12137            } else if ("provider".equals(cmd)) {
12138                String[] newArgs;
12139                String name;
12140                if (opti >= args.length) {
12141                    name = null;
12142                    newArgs = EMPTY_STRING_ARRAY;
12143                } else {
12144                    name = args[opti];
12145                    opti++;
12146                    newArgs = new String[args.length - opti];
12147                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12148                }
12149                if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
12150                    pw.println("No providers match: " + name);
12151                    pw.println("Use -h for help.");
12152                }
12153            } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
12154                synchronized (this) {
12155                    dumpProvidersLocked(fd, pw, args, opti, true, null);
12156                }
12157            } else if ("service".equals(cmd)) {
12158                String[] newArgs;
12159                String name;
12160                if (opti >= args.length) {
12161                    name = null;
12162                    newArgs = EMPTY_STRING_ARRAY;
12163                } else {
12164                    name = args[opti];
12165                    opti++;
12166                    newArgs = new String[args.length - opti];
12167                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12168                            args.length - opti);
12169                }
12170                if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
12171                    pw.println("No services match: " + name);
12172                    pw.println("Use -h for help.");
12173                }
12174            } else if ("package".equals(cmd)) {
12175                String[] newArgs;
12176                if (opti >= args.length) {
12177                    pw.println("package: no package name specified");
12178                    pw.println("Use -h for help.");
12179                } else {
12180                    dumpPackage = args[opti];
12181                    opti++;
12182                    newArgs = new String[args.length - opti];
12183                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
12184                            args.length - opti);
12185                    args = newArgs;
12186                    opti = 0;
12187                    more = true;
12188                }
12189            } else if ("services".equals(cmd) || "s".equals(cmd)) {
12190                synchronized (this) {
12191                    mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
12192                }
12193            } else {
12194                // Dumping a single activity?
12195                if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
12196                    pw.println("Bad activity command, or no activities match: " + cmd);
12197                    pw.println("Use -h for help.");
12198                }
12199            }
12200            if (!more) {
12201                Binder.restoreCallingIdentity(origId);
12202                return;
12203            }
12204        }
12205
12206        // No piece of data specified, dump everything.
12207        synchronized (this) {
12208            dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12209            pw.println();
12210            if (dumpAll) {
12211                pw.println("-------------------------------------------------------------------------------");
12212            }
12213            dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12214            pw.println();
12215            if (dumpAll) {
12216                pw.println("-------------------------------------------------------------------------------");
12217            }
12218            dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12219            pw.println();
12220            if (dumpAll) {
12221                pw.println("-------------------------------------------------------------------------------");
12222            }
12223            mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12224            pw.println();
12225            if (dumpAll) {
12226                pw.println("-------------------------------------------------------------------------------");
12227            }
12228            dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12229            pw.println();
12230            if (dumpAll) {
12231                pw.println("-------------------------------------------------------------------------------");
12232            }
12233            dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
12234            pw.println();
12235            if (dumpAll) {
12236                pw.println("-------------------------------------------------------------------------------");
12237            }
12238            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
12239        }
12240        Binder.restoreCallingIdentity(origId);
12241    }
12242
12243    void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12244            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
12245        pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
12246
12247        boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
12248                dumpPackage);
12249        boolean needSep = printedAnything;
12250
12251        boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
12252                dumpPackage, needSep, "  mFocusedActivity: ");
12253        if (printed) {
12254            printedAnything = true;
12255            needSep = false;
12256        }
12257
12258        if (dumpPackage == null) {
12259            if (needSep) {
12260                pw.println();
12261            }
12262            needSep = true;
12263            printedAnything = true;
12264            mStackSupervisor.dump(pw, "  ");
12265        }
12266
12267        if (!printedAnything) {
12268            pw.println("  (nothing)");
12269        }
12270    }
12271
12272    void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12273            int opti, boolean dumpAll, String dumpPackage) {
12274        pw.println("ACTIVITY MANAGER RECENT ACTIVITIES (dumpsys activity recents)");
12275
12276        boolean printedAnything = false;
12277
12278        if (mRecentTasks.size() > 0) {
12279            boolean printedHeader = false;
12280
12281            final int N = mRecentTasks.size();
12282            for (int i=0; i<N; i++) {
12283                TaskRecord tr = mRecentTasks.get(i);
12284                if (dumpPackage != null) {
12285                    if (tr.realActivity == null ||
12286                            !dumpPackage.equals(tr.realActivity)) {
12287                        continue;
12288                    }
12289                }
12290                if (!printedHeader) {
12291                    pw.println("  Recent tasks:");
12292                    printedHeader = true;
12293                    printedAnything = true;
12294                }
12295                pw.print("  * Recent #"); pw.print(i); pw.print(": ");
12296                        pw.println(tr);
12297                if (dumpAll) {
12298                    mRecentTasks.get(i).dump(pw, "    ");
12299                }
12300            }
12301        }
12302
12303        if (!printedAnything) {
12304            pw.println("  (nothing)");
12305        }
12306    }
12307
12308    void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12309            int opti, boolean dumpAll, String dumpPackage) {
12310        boolean needSep = false;
12311        boolean printedAnything = false;
12312        int numPers = 0;
12313
12314        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
12315
12316        if (dumpAll) {
12317            final int NP = mProcessNames.getMap().size();
12318            for (int ip=0; ip<NP; ip++) {
12319                SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
12320                final int NA = procs.size();
12321                for (int ia=0; ia<NA; ia++) {
12322                    ProcessRecord r = procs.valueAt(ia);
12323                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12324                        continue;
12325                    }
12326                    if (!needSep) {
12327                        pw.println("  All known processes:");
12328                        needSep = true;
12329                        printedAnything = true;
12330                    }
12331                    pw.print(r.persistent ? "  *PERS*" : "  *APP*");
12332                        pw.print(" UID "); pw.print(procs.keyAt(ia));
12333                        pw.print(" "); pw.println(r);
12334                    r.dump(pw, "    ");
12335                    if (r.persistent) {
12336                        numPers++;
12337                    }
12338                }
12339            }
12340        }
12341
12342        if (mIsolatedProcesses.size() > 0) {
12343            boolean printed = false;
12344            for (int i=0; i<mIsolatedProcesses.size(); i++) {
12345                ProcessRecord r = mIsolatedProcesses.valueAt(i);
12346                if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12347                    continue;
12348                }
12349                if (!printed) {
12350                    if (needSep) {
12351                        pw.println();
12352                    }
12353                    pw.println("  Isolated process list (sorted by uid):");
12354                    printedAnything = true;
12355                    printed = true;
12356                    needSep = true;
12357                }
12358                pw.println(String.format("%sIsolated #%2d: %s",
12359                        "    ", i, r.toString()));
12360            }
12361        }
12362
12363        if (mLruProcesses.size() > 0) {
12364            if (needSep) {
12365                pw.println();
12366            }
12367            pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
12368                    pw.print(" total, non-act at ");
12369                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12370                    pw.print(", non-svc at ");
12371                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12372                    pw.println("):");
12373            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
12374            needSep = true;
12375            printedAnything = true;
12376        }
12377
12378        if (dumpAll || dumpPackage != null) {
12379            synchronized (mPidsSelfLocked) {
12380                boolean printed = false;
12381                for (int i=0; i<mPidsSelfLocked.size(); i++) {
12382                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
12383                    if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
12384                        continue;
12385                    }
12386                    if (!printed) {
12387                        if (needSep) pw.println();
12388                        needSep = true;
12389                        pw.println("  PID mappings:");
12390                        printed = true;
12391                        printedAnything = true;
12392                    }
12393                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
12394                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
12395                }
12396            }
12397        }
12398
12399        if (mForegroundProcesses.size() > 0) {
12400            synchronized (mPidsSelfLocked) {
12401                boolean printed = false;
12402                for (int i=0; i<mForegroundProcesses.size(); i++) {
12403                    ProcessRecord r = mPidsSelfLocked.get(
12404                            mForegroundProcesses.valueAt(i).pid);
12405                    if (dumpPackage != null && (r == null
12406                            || !r.pkgList.containsKey(dumpPackage))) {
12407                        continue;
12408                    }
12409                    if (!printed) {
12410                        if (needSep) pw.println();
12411                        needSep = true;
12412                        pw.println("  Foreground Processes:");
12413                        printed = true;
12414                        printedAnything = true;
12415                    }
12416                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
12417                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
12418                }
12419            }
12420        }
12421
12422        if (mPersistentStartingProcesses.size() > 0) {
12423            if (needSep) pw.println();
12424            needSep = true;
12425            printedAnything = true;
12426            pw.println("  Persisent processes that are starting:");
12427            dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
12428                    "Starting Norm", "Restarting PERS", dumpPackage);
12429        }
12430
12431        if (mRemovedProcesses.size() > 0) {
12432            if (needSep) pw.println();
12433            needSep = true;
12434            printedAnything = true;
12435            pw.println("  Processes that are being removed:");
12436            dumpProcessList(pw, this, mRemovedProcesses, "    ",
12437                    "Removed Norm", "Removed PERS", dumpPackage);
12438        }
12439
12440        if (mProcessesOnHold.size() > 0) {
12441            if (needSep) pw.println();
12442            needSep = true;
12443            printedAnything = true;
12444            pw.println("  Processes that are on old until the system is ready:");
12445            dumpProcessList(pw, this, mProcessesOnHold, "    ",
12446                    "OnHold Norm", "OnHold PERS", dumpPackage);
12447        }
12448
12449        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
12450
12451        if (mProcessCrashTimes.getMap().size() > 0) {
12452            boolean printed = false;
12453            long now = SystemClock.uptimeMillis();
12454            final ArrayMap<String, SparseArray<Long>> pmap = mProcessCrashTimes.getMap();
12455            final int NP = pmap.size();
12456            for (int ip=0; ip<NP; ip++) {
12457                String pname = pmap.keyAt(ip);
12458                SparseArray<Long> uids = pmap.valueAt(ip);
12459                final int N = uids.size();
12460                for (int i=0; i<N; i++) {
12461                    int puid = uids.keyAt(i);
12462                    ProcessRecord r = mProcessNames.get(pname, puid);
12463                    if (dumpPackage != null && (r == null
12464                            || !r.pkgList.containsKey(dumpPackage))) {
12465                        continue;
12466                    }
12467                    if (!printed) {
12468                        if (needSep) pw.println();
12469                        needSep = true;
12470                        pw.println("  Time since processes crashed:");
12471                        printed = true;
12472                        printedAnything = true;
12473                    }
12474                    pw.print("    Process "); pw.print(pname);
12475                            pw.print(" uid "); pw.print(puid);
12476                            pw.print(": last crashed ");
12477                            TimeUtils.formatDuration(now-uids.valueAt(i), pw);
12478                            pw.println(" ago");
12479                }
12480            }
12481        }
12482
12483        if (mBadProcesses.getMap().size() > 0) {
12484            boolean printed = false;
12485            final ArrayMap<String, SparseArray<BadProcessInfo>> pmap = mBadProcesses.getMap();
12486            final int NP = pmap.size();
12487            for (int ip=0; ip<NP; ip++) {
12488                String pname = pmap.keyAt(ip);
12489                SparseArray<BadProcessInfo> uids = pmap.valueAt(ip);
12490                final int N = uids.size();
12491                for (int i=0; i<N; i++) {
12492                    int puid = uids.keyAt(i);
12493                    ProcessRecord r = mProcessNames.get(pname, puid);
12494                    if (dumpPackage != null && (r == null
12495                            || !r.pkgList.containsKey(dumpPackage))) {
12496                        continue;
12497                    }
12498                    if (!printed) {
12499                        if (needSep) pw.println();
12500                        needSep = true;
12501                        pw.println("  Bad processes:");
12502                        printedAnything = true;
12503                    }
12504                    BadProcessInfo info = uids.valueAt(i);
12505                    pw.print("    Bad process "); pw.print(pname);
12506                            pw.print(" uid "); pw.print(puid);
12507                            pw.print(": crashed at time "); pw.println(info.time);
12508                    if (info.shortMsg != null) {
12509                        pw.print("      Short msg: "); pw.println(info.shortMsg);
12510                    }
12511                    if (info.longMsg != null) {
12512                        pw.print("      Long msg: "); pw.println(info.longMsg);
12513                    }
12514                    if (info.stack != null) {
12515                        pw.println("      Stack:");
12516                        int lastPos = 0;
12517                        for (int pos=0; pos<info.stack.length(); pos++) {
12518                            if (info.stack.charAt(pos) == '\n') {
12519                                pw.print("        ");
12520                                pw.write(info.stack, lastPos, pos-lastPos);
12521                                pw.println();
12522                                lastPos = pos+1;
12523                            }
12524                        }
12525                        if (lastPos < info.stack.length()) {
12526                            pw.print("        ");
12527                            pw.write(info.stack, lastPos, info.stack.length()-lastPos);
12528                            pw.println();
12529                        }
12530                    }
12531                }
12532            }
12533        }
12534
12535        if (dumpPackage == null) {
12536            pw.println();
12537            needSep = false;
12538            pw.println("  mStartedUsers:");
12539            for (int i=0; i<mStartedUsers.size(); i++) {
12540                UserStartedState uss = mStartedUsers.valueAt(i);
12541                pw.print("    User #"); pw.print(uss.mHandle.getIdentifier());
12542                        pw.print(": "); uss.dump("", pw);
12543            }
12544            pw.print("  mStartedUserArray: [");
12545            for (int i=0; i<mStartedUserArray.length; i++) {
12546                if (i > 0) pw.print(", ");
12547                pw.print(mStartedUserArray[i]);
12548            }
12549            pw.println("]");
12550            pw.print("  mUserLru: [");
12551            for (int i=0; i<mUserLru.size(); i++) {
12552                if (i > 0) pw.print(", ");
12553                pw.print(mUserLru.get(i));
12554            }
12555            pw.println("]");
12556            if (dumpAll) {
12557                pw.print("  mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
12558            }
12559            synchronized (mUserProfileGroupIdsSelfLocked) {
12560                if (mUserProfileGroupIdsSelfLocked.size() > 0) {
12561                    pw.println("  mUserProfileGroupIds:");
12562                    for (int i=0; i<mUserProfileGroupIdsSelfLocked.size(); i++) {
12563                        pw.print("    User #");
12564                        pw.print(mUserProfileGroupIdsSelfLocked.keyAt(i));
12565                        pw.print(" -> profile #");
12566                        pw.println(mUserProfileGroupIdsSelfLocked.valueAt(i));
12567                    }
12568                }
12569            }
12570        }
12571        if (mHomeProcess != null && (dumpPackage == null
12572                || mHomeProcess.pkgList.containsKey(dumpPackage))) {
12573            if (needSep) {
12574                pw.println();
12575                needSep = false;
12576            }
12577            pw.println("  mHomeProcess: " + mHomeProcess);
12578        }
12579        if (mPreviousProcess != null && (dumpPackage == null
12580                || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
12581            if (needSep) {
12582                pw.println();
12583                needSep = false;
12584            }
12585            pw.println("  mPreviousProcess: " + mPreviousProcess);
12586        }
12587        if (dumpAll) {
12588            StringBuilder sb = new StringBuilder(128);
12589            sb.append("  mPreviousProcessVisibleTime: ");
12590            TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
12591            pw.println(sb);
12592        }
12593        if (mHeavyWeightProcess != null && (dumpPackage == null
12594                || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
12595            if (needSep) {
12596                pw.println();
12597                needSep = false;
12598            }
12599            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12600        }
12601        if (dumpPackage == null) {
12602            pw.println("  mConfiguration: " + mConfiguration);
12603        }
12604        if (dumpAll) {
12605            pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
12606            if (mCompatModePackages.getPackages().size() > 0) {
12607                boolean printed = false;
12608                for (Map.Entry<String, Integer> entry
12609                        : mCompatModePackages.getPackages().entrySet()) {
12610                    String pkg = entry.getKey();
12611                    int mode = entry.getValue();
12612                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
12613                        continue;
12614                    }
12615                    if (!printed) {
12616                        pw.println("  mScreenCompatPackages:");
12617                        printed = true;
12618                    }
12619                    pw.print("    "); pw.print(pkg); pw.print(": ");
12620                            pw.print(mode); pw.println();
12621                }
12622            }
12623        }
12624        if (dumpPackage == null) {
12625            if (mSleeping || mWentToSleep || mLockScreenShown) {
12626                pw.println("  mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
12627                        + " mLockScreenShown " + mLockScreenShown);
12628            }
12629            if (mShuttingDown || mRunningVoice) {
12630                pw.print("  mShuttingDown=" + mShuttingDown + " mRunningVoice=" + mRunningVoice);
12631            }
12632        }
12633        if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
12634                || mOrigWaitForDebugger) {
12635            if (dumpPackage == null || dumpPackage.equals(mDebugApp)
12636                    || dumpPackage.equals(mOrigDebugApp)) {
12637                if (needSep) {
12638                    pw.println();
12639                    needSep = false;
12640                }
12641                pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
12642                        + " mDebugTransient=" + mDebugTransient
12643                        + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
12644            }
12645        }
12646        if (mOpenGlTraceApp != null) {
12647            if (dumpPackage == null || dumpPackage.equals(mOpenGlTraceApp)) {
12648                if (needSep) {
12649                    pw.println();
12650                    needSep = false;
12651                }
12652                pw.println("  mOpenGlTraceApp=" + mOpenGlTraceApp);
12653            }
12654        }
12655        if (mProfileApp != null || mProfileProc != null || mProfileFile != null
12656                || mProfileFd != null) {
12657            if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
12658                if (needSep) {
12659                    pw.println();
12660                    needSep = false;
12661                }
12662                pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
12663                pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
12664                pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
12665                        + mAutoStopProfiler);
12666                pw.println("  mProfileType=" + mProfileType);
12667            }
12668        }
12669        if (dumpPackage == null) {
12670            if (mAlwaysFinishActivities || mController != null) {
12671                pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
12672                        + " mController=" + mController);
12673            }
12674            if (dumpAll) {
12675                pw.println("  Total persistent processes: " + numPers);
12676                pw.println("  mProcessesReady=" + mProcessesReady
12677                        + " mSystemReady=" + mSystemReady);
12678                pw.println("  mBooting=" + mBooting
12679                        + " mBooted=" + mBooted
12680                        + " mFactoryTest=" + mFactoryTest);
12681                pw.print("  mLastPowerCheckRealtime=");
12682                        TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
12683                        pw.println("");
12684                pw.print("  mLastPowerCheckUptime=");
12685                        TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
12686                        pw.println("");
12687                pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
12688                pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
12689                pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
12690                pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
12691                        + " (" + mLruProcesses.size() + " total)"
12692                        + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
12693                        + " mNumServiceProcs=" + mNumServiceProcs
12694                        + " mNewNumServiceProcs=" + mNewNumServiceProcs);
12695                pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
12696                        + " mLastMemoryLevel" + mLastMemoryLevel
12697                        + " mLastNumProcesses" + mLastNumProcesses);
12698                long now = SystemClock.uptimeMillis();
12699                pw.print("  mLastIdleTime=");
12700                        TimeUtils.formatDuration(now, mLastIdleTime, pw);
12701                        pw.print(" mLowRamSinceLastIdle=");
12702                        TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
12703                        pw.println();
12704            }
12705        }
12706
12707        if (!printedAnything) {
12708            pw.println("  (nothing)");
12709        }
12710    }
12711
12712    boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
12713            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
12714        if (mProcessesToGc.size() > 0) {
12715            boolean printed = false;
12716            long now = SystemClock.uptimeMillis();
12717            for (int i=0; i<mProcessesToGc.size(); i++) {
12718                ProcessRecord proc = mProcessesToGc.get(i);
12719                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
12720                    continue;
12721                }
12722                if (!printed) {
12723                    if (needSep) pw.println();
12724                    needSep = true;
12725                    pw.println("  Processes that are waiting to GC:");
12726                    printed = true;
12727                }
12728                pw.print("    Process "); pw.println(proc);
12729                pw.print("      lowMem="); pw.print(proc.reportLowMemory);
12730                        pw.print(", last gced=");
12731                        pw.print(now-proc.lastRequestedGc);
12732                        pw.print(" ms ago, last lowMem=");
12733                        pw.print(now-proc.lastLowMemory);
12734                        pw.println(" ms ago");
12735
12736            }
12737        }
12738        return needSep;
12739    }
12740
12741    void printOomLevel(PrintWriter pw, String name, int adj) {
12742        pw.print("    ");
12743        if (adj >= 0) {
12744            pw.print(' ');
12745            if (adj < 10) pw.print(' ');
12746        } else {
12747            if (adj > -10) pw.print(' ');
12748        }
12749        pw.print(adj);
12750        pw.print(": ");
12751        pw.print(name);
12752        pw.print(" (");
12753        pw.print(mProcessList.getMemLevel(adj)/1024);
12754        pw.println(" kB)");
12755    }
12756
12757    boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12758            int opti, boolean dumpAll) {
12759        boolean needSep = false;
12760
12761        if (mLruProcesses.size() > 0) {
12762            if (needSep) pw.println();
12763            needSep = true;
12764            pw.println("  OOM levels:");
12765            printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
12766            printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
12767            printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
12768            printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
12769            printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
12770            printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
12771            printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
12772            printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
12773            printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
12774            printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
12775            printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
12776            printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
12777            printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
12778
12779            if (needSep) pw.println();
12780            pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
12781                    pw.print(" total, non-act at ");
12782                    pw.print(mLruProcesses.size()-mLruProcessActivityStart);
12783                    pw.print(", non-svc at ");
12784                    pw.print(mLruProcesses.size()-mLruProcessServiceStart);
12785                    pw.println("):");
12786            dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
12787            needSep = true;
12788        }
12789
12790        dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
12791
12792        pw.println();
12793        pw.println("  mHomeProcess: " + mHomeProcess);
12794        pw.println("  mPreviousProcess: " + mPreviousProcess);
12795        if (mHeavyWeightProcess != null) {
12796            pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
12797        }
12798
12799        return true;
12800    }
12801
12802    /**
12803     * There are three ways to call this:
12804     *  - no provider specified: dump all the providers
12805     *  - a flattened component name that matched an existing provider was specified as the
12806     *    first arg: dump that one provider
12807     *  - the first arg isn't the flattened component name of an existing provider:
12808     *    dump all providers whose component contains the first arg as a substring
12809     */
12810    protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12811            int opti, boolean dumpAll) {
12812        return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
12813    }
12814
12815    static class ItemMatcher {
12816        ArrayList<ComponentName> components;
12817        ArrayList<String> strings;
12818        ArrayList<Integer> objects;
12819        boolean all;
12820
12821        ItemMatcher() {
12822            all = true;
12823        }
12824
12825        void build(String name) {
12826            ComponentName componentName = ComponentName.unflattenFromString(name);
12827            if (componentName != null) {
12828                if (components == null) {
12829                    components = new ArrayList<ComponentName>();
12830                }
12831                components.add(componentName);
12832                all = false;
12833            } else {
12834                int objectId = 0;
12835                // Not a '/' separated full component name; maybe an object ID?
12836                try {
12837                    objectId = Integer.parseInt(name, 16);
12838                    if (objects == null) {
12839                        objects = new ArrayList<Integer>();
12840                    }
12841                    objects.add(objectId);
12842                    all = false;
12843                } catch (RuntimeException e) {
12844                    // Not an integer; just do string match.
12845                    if (strings == null) {
12846                        strings = new ArrayList<String>();
12847                    }
12848                    strings.add(name);
12849                    all = false;
12850                }
12851            }
12852        }
12853
12854        int build(String[] args, int opti) {
12855            for (; opti<args.length; opti++) {
12856                String name = args[opti];
12857                if ("--".equals(name)) {
12858                    return opti+1;
12859                }
12860                build(name);
12861            }
12862            return opti;
12863        }
12864
12865        boolean match(Object object, ComponentName comp) {
12866            if (all) {
12867                return true;
12868            }
12869            if (components != null) {
12870                for (int i=0; i<components.size(); i++) {
12871                    if (components.get(i).equals(comp)) {
12872                        return true;
12873                    }
12874                }
12875            }
12876            if (objects != null) {
12877                for (int i=0; i<objects.size(); i++) {
12878                    if (System.identityHashCode(object) == objects.get(i)) {
12879                        return true;
12880                    }
12881                }
12882            }
12883            if (strings != null) {
12884                String flat = comp.flattenToString();
12885                for (int i=0; i<strings.size(); i++) {
12886                    if (flat.contains(strings.get(i))) {
12887                        return true;
12888                    }
12889                }
12890            }
12891            return false;
12892        }
12893    }
12894
12895    /**
12896     * There are three things that cmd can be:
12897     *  - a flattened component name that matches an existing activity
12898     *  - the cmd arg isn't the flattened component name of an existing activity:
12899     *    dump all activity whose component contains the cmd as a substring
12900     *  - A hex number of the ActivityRecord object instance.
12901     */
12902    protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
12903            int opti, boolean dumpAll) {
12904        ArrayList<ActivityRecord> activities;
12905
12906        synchronized (this) {
12907            activities = mStackSupervisor.getDumpActivitiesLocked(name);
12908        }
12909
12910        if (activities.size() <= 0) {
12911            return false;
12912        }
12913
12914        String[] newArgs = new String[args.length - opti];
12915        System.arraycopy(args, opti, newArgs, 0, args.length - opti);
12916
12917        TaskRecord lastTask = null;
12918        boolean needSep = false;
12919        for (int i=activities.size()-1; i>=0; i--) {
12920            ActivityRecord r = activities.get(i);
12921            if (needSep) {
12922                pw.println();
12923            }
12924            needSep = true;
12925            synchronized (this) {
12926                if (lastTask != r.task) {
12927                    lastTask = r.task;
12928                    pw.print("TASK "); pw.print(lastTask.affinity);
12929                            pw.print(" id="); pw.println(lastTask.taskId);
12930                    if (dumpAll) {
12931                        lastTask.dump(pw, "  ");
12932                    }
12933                }
12934            }
12935            dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
12936        }
12937        return true;
12938    }
12939
12940    /**
12941     * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
12942     * there is a thread associated with the activity.
12943     */
12944    private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
12945            final ActivityRecord r, String[] args, boolean dumpAll) {
12946        String innerPrefix = prefix + "  ";
12947        synchronized (this) {
12948            pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
12949                    pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
12950                    pw.print(" pid=");
12951                    if (r.app != null) pw.println(r.app.pid);
12952                    else pw.println("(not running)");
12953            if (dumpAll) {
12954                r.dump(pw, innerPrefix);
12955            }
12956        }
12957        if (r.app != null && r.app.thread != null) {
12958            // flush anything that is already in the PrintWriter since the thread is going
12959            // to write to the file descriptor directly
12960            pw.flush();
12961            try {
12962                TransferPipe tp = new TransferPipe();
12963                try {
12964                    r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
12965                            r.appToken, innerPrefix, args);
12966                    tp.go(fd);
12967                } finally {
12968                    tp.kill();
12969                }
12970            } catch (IOException e) {
12971                pw.println(innerPrefix + "Failure while dumping the activity: " + e);
12972            } catch (RemoteException e) {
12973                pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
12974            }
12975        }
12976    }
12977
12978    void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
12979            int opti, boolean dumpAll, String dumpPackage) {
12980        boolean needSep = false;
12981        boolean onlyHistory = false;
12982        boolean printedAnything = false;
12983
12984        if ("history".equals(dumpPackage)) {
12985            if (opti < args.length && "-s".equals(args[opti])) {
12986                dumpAll = false;
12987            }
12988            onlyHistory = true;
12989            dumpPackage = null;
12990        }
12991
12992        pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
12993        if (!onlyHistory && dumpAll) {
12994            if (mRegisteredReceivers.size() > 0) {
12995                boolean printed = false;
12996                Iterator it = mRegisteredReceivers.values().iterator();
12997                while (it.hasNext()) {
12998                    ReceiverList r = (ReceiverList)it.next();
12999                    if (dumpPackage != null && (r.app == null ||
13000                            !dumpPackage.equals(r.app.info.packageName))) {
13001                        continue;
13002                    }
13003                    if (!printed) {
13004                        pw.println("  Registered Receivers:");
13005                        needSep = true;
13006                        printed = true;
13007                        printedAnything = true;
13008                    }
13009                    pw.print("  * "); pw.println(r);
13010                    r.dump(pw, "    ");
13011                }
13012            }
13013
13014            if (mReceiverResolver.dump(pw, needSep ?
13015                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
13016                    "    ", dumpPackage, false)) {
13017                needSep = true;
13018                printedAnything = true;
13019            }
13020        }
13021
13022        for (BroadcastQueue q : mBroadcastQueues) {
13023            needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
13024            printedAnything |= needSep;
13025        }
13026
13027        needSep = true;
13028
13029        if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
13030            for (int user=0; user<mStickyBroadcasts.size(); user++) {
13031                if (needSep) {
13032                    pw.println();
13033                }
13034                needSep = true;
13035                printedAnything = true;
13036                pw.print("  Sticky broadcasts for user ");
13037                        pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
13038                StringBuilder sb = new StringBuilder(128);
13039                for (Map.Entry<String, ArrayList<Intent>> ent
13040                        : mStickyBroadcasts.valueAt(user).entrySet()) {
13041                    pw.print("  * Sticky action "); pw.print(ent.getKey());
13042                    if (dumpAll) {
13043                        pw.println(":");
13044                        ArrayList<Intent> intents = ent.getValue();
13045                        final int N = intents.size();
13046                        for (int i=0; i<N; i++) {
13047                            sb.setLength(0);
13048                            sb.append("    Intent: ");
13049                            intents.get(i).toShortString(sb, false, true, false, false);
13050                            pw.println(sb.toString());
13051                            Bundle bundle = intents.get(i).getExtras();
13052                            if (bundle != null) {
13053                                pw.print("      ");
13054                                pw.println(bundle.toString());
13055                            }
13056                        }
13057                    } else {
13058                        pw.println("");
13059                    }
13060                }
13061            }
13062        }
13063
13064        if (!onlyHistory && dumpAll) {
13065            pw.println();
13066            for (BroadcastQueue queue : mBroadcastQueues) {
13067                pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
13068                        + queue.mBroadcastsScheduled);
13069            }
13070            pw.println("  mHandler:");
13071            mHandler.dump(new PrintWriterPrinter(pw), "    ");
13072            needSep = true;
13073            printedAnything = true;
13074        }
13075
13076        if (!printedAnything) {
13077            pw.println("  (nothing)");
13078        }
13079    }
13080
13081    void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13082            int opti, boolean dumpAll, String dumpPackage) {
13083        boolean needSep;
13084        boolean printedAnything = false;
13085
13086        ItemMatcher matcher = new ItemMatcher();
13087        matcher.build(args, opti);
13088
13089        pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
13090
13091        needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
13092        printedAnything |= needSep;
13093
13094        if (mLaunchingProviders.size() > 0) {
13095            boolean printed = false;
13096            for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
13097                ContentProviderRecord r = mLaunchingProviders.get(i);
13098                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
13099                    continue;
13100                }
13101                if (!printed) {
13102                    if (needSep) pw.println();
13103                    needSep = true;
13104                    pw.println("  Launching content providers:");
13105                    printed = true;
13106                    printedAnything = true;
13107                }
13108                pw.print("  Launching #"); pw.print(i); pw.print(": ");
13109                        pw.println(r);
13110            }
13111        }
13112
13113        if (mGrantedUriPermissions.size() > 0) {
13114            boolean printed = false;
13115            int dumpUid = -2;
13116            if (dumpPackage != null) {
13117                try {
13118                    dumpUid = mContext.getPackageManager().getPackageUid(dumpPackage, 0);
13119                } catch (NameNotFoundException e) {
13120                    dumpUid = -1;
13121                }
13122            }
13123            for (int i=0; i<mGrantedUriPermissions.size(); i++) {
13124                int uid = mGrantedUriPermissions.keyAt(i);
13125                if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
13126                    continue;
13127                }
13128                final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
13129                if (!printed) {
13130                    if (needSep) pw.println();
13131                    needSep = true;
13132                    pw.println("  Granted Uri Permissions:");
13133                    printed = true;
13134                    printedAnything = true;
13135                }
13136                pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
13137                for (UriPermission perm : perms.values()) {
13138                    pw.print("    "); pw.println(perm);
13139                    if (dumpAll) {
13140                        perm.dump(pw, "      ");
13141                    }
13142                }
13143            }
13144        }
13145
13146        if (!printedAnything) {
13147            pw.println("  (nothing)");
13148        }
13149    }
13150
13151    void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13152            int opti, boolean dumpAll, String dumpPackage) {
13153        boolean printed = false;
13154
13155        pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
13156
13157        if (mIntentSenderRecords.size() > 0) {
13158            Iterator<WeakReference<PendingIntentRecord>> it
13159                    = mIntentSenderRecords.values().iterator();
13160            while (it.hasNext()) {
13161                WeakReference<PendingIntentRecord> ref = it.next();
13162                PendingIntentRecord rec = ref != null ? ref.get(): null;
13163                if (dumpPackage != null && (rec == null
13164                        || !dumpPackage.equals(rec.key.packageName))) {
13165                    continue;
13166                }
13167                printed = true;
13168                if (rec != null) {
13169                    pw.print("  * "); pw.println(rec);
13170                    if (dumpAll) {
13171                        rec.dump(pw, "    ");
13172                    }
13173                } else {
13174                    pw.print("  * "); pw.println(ref);
13175                }
13176            }
13177        }
13178
13179        if (!printed) {
13180            pw.println("  (nothing)");
13181        }
13182    }
13183
13184    private static final int dumpProcessList(PrintWriter pw,
13185            ActivityManagerService service, List list,
13186            String prefix, String normalLabel, String persistentLabel,
13187            String dumpPackage) {
13188        int numPers = 0;
13189        final int N = list.size()-1;
13190        for (int i=N; i>=0; i--) {
13191            ProcessRecord r = (ProcessRecord)list.get(i);
13192            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
13193                continue;
13194            }
13195            pw.println(String.format("%s%s #%2d: %s",
13196                    prefix, (r.persistent ? persistentLabel : normalLabel),
13197                    i, r.toString()));
13198            if (r.persistent) {
13199                numPers++;
13200            }
13201        }
13202        return numPers;
13203    }
13204
13205    private static final boolean dumpProcessOomList(PrintWriter pw,
13206            ActivityManagerService service, List<ProcessRecord> origList,
13207            String prefix, String normalLabel, String persistentLabel,
13208            boolean inclDetails, String dumpPackage) {
13209
13210        ArrayList<Pair<ProcessRecord, Integer>> list
13211                = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
13212        for (int i=0; i<origList.size(); i++) {
13213            ProcessRecord r = origList.get(i);
13214            if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
13215                continue;
13216            }
13217            list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
13218        }
13219
13220        if (list.size() <= 0) {
13221            return false;
13222        }
13223
13224        Comparator<Pair<ProcessRecord, Integer>> comparator
13225                = new Comparator<Pair<ProcessRecord, Integer>>() {
13226            @Override
13227            public int compare(Pair<ProcessRecord, Integer> object1,
13228                    Pair<ProcessRecord, Integer> object2) {
13229                if (object1.first.setAdj != object2.first.setAdj) {
13230                    return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
13231                }
13232                if (object1.second.intValue() != object2.second.intValue()) {
13233                    return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
13234                }
13235                return 0;
13236            }
13237        };
13238
13239        Collections.sort(list, comparator);
13240
13241        final long curRealtime = SystemClock.elapsedRealtime();
13242        final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
13243        final long curUptime = SystemClock.uptimeMillis();
13244        final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
13245
13246        for (int i=list.size()-1; i>=0; i--) {
13247            ProcessRecord r = list.get(i).first;
13248            String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
13249            char schedGroup;
13250            switch (r.setSchedGroup) {
13251                case Process.THREAD_GROUP_BG_NONINTERACTIVE:
13252                    schedGroup = 'B';
13253                    break;
13254                case Process.THREAD_GROUP_DEFAULT:
13255                    schedGroup = 'F';
13256                    break;
13257                default:
13258                    schedGroup = '?';
13259                    break;
13260            }
13261            char foreground;
13262            if (r.foregroundActivities) {
13263                foreground = 'A';
13264            } else if (r.foregroundServices) {
13265                foreground = 'S';
13266            } else {
13267                foreground = ' ';
13268            }
13269            String procState = ProcessList.makeProcStateString(r.curProcState);
13270            pw.print(prefix);
13271            pw.print(r.persistent ? persistentLabel : normalLabel);
13272            pw.print(" #");
13273            int num = (origList.size()-1)-list.get(i).second;
13274            if (num < 10) pw.print(' ');
13275            pw.print(num);
13276            pw.print(": ");
13277            pw.print(oomAdj);
13278            pw.print(' ');
13279            pw.print(schedGroup);
13280            pw.print('/');
13281            pw.print(foreground);
13282            pw.print('/');
13283            pw.print(procState);
13284            pw.print(" trm:");
13285            if (r.trimMemoryLevel < 10) pw.print(' ');
13286            pw.print(r.trimMemoryLevel);
13287            pw.print(' ');
13288            pw.print(r.toShortString());
13289            pw.print(" (");
13290            pw.print(r.adjType);
13291            pw.println(')');
13292            if (r.adjSource != null || r.adjTarget != null) {
13293                pw.print(prefix);
13294                pw.print("    ");
13295                if (r.adjTarget instanceof ComponentName) {
13296                    pw.print(((ComponentName)r.adjTarget).flattenToShortString());
13297                } else if (r.adjTarget != null) {
13298                    pw.print(r.adjTarget.toString());
13299                } else {
13300                    pw.print("{null}");
13301                }
13302                pw.print("<=");
13303                if (r.adjSource instanceof ProcessRecord) {
13304                    pw.print("Proc{");
13305                    pw.print(((ProcessRecord)r.adjSource).toShortString());
13306                    pw.println("}");
13307                } else if (r.adjSource != null) {
13308                    pw.println(r.adjSource.toString());
13309                } else {
13310                    pw.println("{null}");
13311                }
13312            }
13313            if (inclDetails) {
13314                pw.print(prefix);
13315                pw.print("    ");
13316                pw.print("oom: max="); pw.print(r.maxAdj);
13317                pw.print(" curRaw="); pw.print(r.curRawAdj);
13318                pw.print(" setRaw="); pw.print(r.setRawAdj);
13319                pw.print(" cur="); pw.print(r.curAdj);
13320                pw.print(" set="); pw.println(r.setAdj);
13321                pw.print(prefix);
13322                pw.print("    ");
13323                pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
13324                pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
13325                pw.print(" lastPss="); pw.print(r.lastPss);
13326                pw.print(" lastCachedPss="); pw.println(r.lastCachedPss);
13327                pw.print(prefix);
13328                pw.print("    ");
13329                pw.print("cached="); pw.print(r.cached);
13330                pw.print(" empty="); pw.print(r.empty);
13331                pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
13332
13333                if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
13334                    if (r.lastWakeTime != 0) {
13335                        long wtime;
13336                        BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
13337                        synchronized (stats) {
13338                            wtime = stats.getProcessWakeTime(r.info.uid,
13339                                    r.pid, curRealtime);
13340                        }
13341                        long timeUsed = wtime - r.lastWakeTime;
13342                        pw.print(prefix);
13343                        pw.print("    ");
13344                        pw.print("keep awake over ");
13345                        TimeUtils.formatDuration(realtimeSince, pw);
13346                        pw.print(" used ");
13347                        TimeUtils.formatDuration(timeUsed, pw);
13348                        pw.print(" (");
13349                        pw.print((timeUsed*100)/realtimeSince);
13350                        pw.println("%)");
13351                    }
13352                    if (r.lastCpuTime != 0) {
13353                        long timeUsed = r.curCpuTime - r.lastCpuTime;
13354                        pw.print(prefix);
13355                        pw.print("    ");
13356                        pw.print("run cpu over ");
13357                        TimeUtils.formatDuration(uptimeSince, pw);
13358                        pw.print(" used ");
13359                        TimeUtils.formatDuration(timeUsed, pw);
13360                        pw.print(" (");
13361                        pw.print((timeUsed*100)/uptimeSince);
13362                        pw.println("%)");
13363                    }
13364                }
13365            }
13366        }
13367        return true;
13368    }
13369
13370    ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
13371        ArrayList<ProcessRecord> procs;
13372        synchronized (this) {
13373            if (args != null && args.length > start
13374                    && args[start].charAt(0) != '-') {
13375                procs = new ArrayList<ProcessRecord>();
13376                int pid = -1;
13377                try {
13378                    pid = Integer.parseInt(args[start]);
13379                } catch (NumberFormatException e) {
13380                }
13381                for (int i=mLruProcesses.size()-1; i>=0; i--) {
13382                    ProcessRecord proc = mLruProcesses.get(i);
13383                    if (proc.pid == pid) {
13384                        procs.add(proc);
13385                    } else if (proc.processName.equals(args[start])) {
13386                        procs.add(proc);
13387                    }
13388                }
13389                if (procs.size() <= 0) {
13390                    return null;
13391                }
13392            } else {
13393                procs = new ArrayList<ProcessRecord>(mLruProcesses);
13394            }
13395        }
13396        return procs;
13397    }
13398
13399    final void dumpGraphicsHardwareUsage(FileDescriptor fd,
13400            PrintWriter pw, String[] args) {
13401        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13402        if (procs == null) {
13403            pw.println("No process found for: " + args[0]);
13404            return;
13405        }
13406
13407        long uptime = SystemClock.uptimeMillis();
13408        long realtime = SystemClock.elapsedRealtime();
13409        pw.println("Applications Graphics Acceleration Info:");
13410        pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13411
13412        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13413            ProcessRecord r = procs.get(i);
13414            if (r.thread != null) {
13415                pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
13416                pw.flush();
13417                try {
13418                    TransferPipe tp = new TransferPipe();
13419                    try {
13420                        r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
13421                        tp.go(fd);
13422                    } finally {
13423                        tp.kill();
13424                    }
13425                } catch (IOException e) {
13426                    pw.println("Failure while dumping the app: " + r);
13427                    pw.flush();
13428                } catch (RemoteException e) {
13429                    pw.println("Got a RemoteException while dumping the app " + r);
13430                    pw.flush();
13431                }
13432            }
13433        }
13434    }
13435
13436    final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
13437        ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
13438        if (procs == null) {
13439            pw.println("No process found for: " + args[0]);
13440            return;
13441        }
13442
13443        pw.println("Applications Database Info:");
13444
13445        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13446            ProcessRecord r = procs.get(i);
13447            if (r.thread != null) {
13448                pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
13449                pw.flush();
13450                try {
13451                    TransferPipe tp = new TransferPipe();
13452                    try {
13453                        r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
13454                        tp.go(fd);
13455                    } finally {
13456                        tp.kill();
13457                    }
13458                } catch (IOException e) {
13459                    pw.println("Failure while dumping the app: " + r);
13460                    pw.flush();
13461                } catch (RemoteException e) {
13462                    pw.println("Got a RemoteException while dumping the app " + r);
13463                    pw.flush();
13464                }
13465            }
13466        }
13467    }
13468
13469    final static class MemItem {
13470        final boolean isProc;
13471        final String label;
13472        final String shortLabel;
13473        final long pss;
13474        final int id;
13475        final boolean hasActivities;
13476        ArrayList<MemItem> subitems;
13477
13478        public MemItem(String _label, String _shortLabel, long _pss, int _id,
13479                boolean _hasActivities) {
13480            isProc = true;
13481            label = _label;
13482            shortLabel = _shortLabel;
13483            pss = _pss;
13484            id = _id;
13485            hasActivities = _hasActivities;
13486        }
13487
13488        public MemItem(String _label, String _shortLabel, long _pss, int _id) {
13489            isProc = false;
13490            label = _label;
13491            shortLabel = _shortLabel;
13492            pss = _pss;
13493            id = _id;
13494            hasActivities = false;
13495        }
13496    }
13497
13498    static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
13499            ArrayList<MemItem> items, boolean sort, boolean isCompact) {
13500        if (sort && !isCompact) {
13501            Collections.sort(items, new Comparator<MemItem>() {
13502                @Override
13503                public int compare(MemItem lhs, MemItem rhs) {
13504                    if (lhs.pss < rhs.pss) {
13505                        return 1;
13506                    } else if (lhs.pss > rhs.pss) {
13507                        return -1;
13508                    }
13509                    return 0;
13510                }
13511            });
13512        }
13513
13514        for (int i=0; i<items.size(); i++) {
13515            MemItem mi = items.get(i);
13516            if (!isCompact) {
13517                pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
13518            } else if (mi.isProc) {
13519                pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
13520                pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss);
13521                pw.println(mi.hasActivities ? ",a" : ",e");
13522            } else {
13523                pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
13524                pw.println(mi.pss);
13525            }
13526            if (mi.subitems != null) {
13527                dumpMemItems(pw, prefix + "           ", mi.shortLabel, mi.subitems,
13528                        true, isCompact);
13529            }
13530        }
13531    }
13532
13533    // These are in KB.
13534    static final long[] DUMP_MEM_BUCKETS = new long[] {
13535        5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
13536        120*1024, 160*1024, 200*1024,
13537        250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
13538        1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
13539    };
13540
13541    static final void appendMemBucket(StringBuilder out, long memKB, String label,
13542            boolean stackLike) {
13543        int start = label.lastIndexOf('.');
13544        if (start >= 0) start++;
13545        else start = 0;
13546        int end = label.length();
13547        for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
13548            if (DUMP_MEM_BUCKETS[i] >= memKB) {
13549                long bucket = DUMP_MEM_BUCKETS[i]/1024;
13550                out.append(bucket);
13551                out.append(stackLike ? "MB." : "MB ");
13552                out.append(label, start, end);
13553                return;
13554            }
13555        }
13556        out.append(memKB/1024);
13557        out.append(stackLike ? "MB." : "MB ");
13558        out.append(label, start, end);
13559    }
13560
13561    static final int[] DUMP_MEM_OOM_ADJ = new int[] {
13562            ProcessList.NATIVE_ADJ,
13563            ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
13564            ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
13565            ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
13566            ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
13567            ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
13568    };
13569    static final String[] DUMP_MEM_OOM_LABEL = new String[] {
13570            "Native",
13571            "System", "Persistent", "Foreground",
13572            "Visible", "Perceptible",
13573            "Heavy Weight", "Backup",
13574            "A Services", "Home",
13575            "Previous", "B Services", "Cached"
13576    };
13577    static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
13578            "native",
13579            "sys", "pers", "fore",
13580            "vis", "percept",
13581            "heavy", "backup",
13582            "servicea", "home",
13583            "prev", "serviceb", "cached"
13584    };
13585
13586    private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
13587            long realtime, boolean isCheckinRequest, boolean isCompact) {
13588        if (isCheckinRequest || isCompact) {
13589            // short checkin version
13590            pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
13591        } else {
13592            pw.println("Applications Memory Usage (kB):");
13593            pw.println("Uptime: " + uptime + " Realtime: " + realtime);
13594        }
13595    }
13596
13597    final void dumpApplicationMemoryUsage(FileDescriptor fd,
13598            PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
13599        boolean dumpDetails = false;
13600        boolean dumpFullDetails = false;
13601        boolean dumpDalvik = false;
13602        boolean oomOnly = false;
13603        boolean isCompact = false;
13604        boolean localOnly = false;
13605
13606        int opti = 0;
13607        while (opti < args.length) {
13608            String opt = args[opti];
13609            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13610                break;
13611            }
13612            opti++;
13613            if ("-a".equals(opt)) {
13614                dumpDetails = true;
13615                dumpFullDetails = true;
13616                dumpDalvik = true;
13617            } else if ("-d".equals(opt)) {
13618                dumpDalvik = true;
13619            } else if ("-c".equals(opt)) {
13620                isCompact = true;
13621            } else if ("--oom".equals(opt)) {
13622                oomOnly = true;
13623            } else if ("--local".equals(opt)) {
13624                localOnly = true;
13625            } else if ("-h".equals(opt)) {
13626                pw.println("meminfo dump options: [-a] [-d] [-c] [--oom] [process]");
13627                pw.println("  -a: include all available information for each process.");
13628                pw.println("  -d: include dalvik details when dumping process details.");
13629                pw.println("  -c: dump in a compact machine-parseable representation.");
13630                pw.println("  --oom: only show processes organized by oom adj.");
13631                pw.println("  --local: only collect details locally, don't call process.");
13632                pw.println("If [process] is specified it can be the name or ");
13633                pw.println("pid of a specific process to dump.");
13634                return;
13635            } else {
13636                pw.println("Unknown argument: " + opt + "; use -h for help");
13637            }
13638        }
13639
13640        final boolean isCheckinRequest = scanArgs(args, "--checkin");
13641        long uptime = SystemClock.uptimeMillis();
13642        long realtime = SystemClock.elapsedRealtime();
13643        final long[] tmpLong = new long[1];
13644
13645        ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
13646        if (procs == null) {
13647            // No Java processes.  Maybe they want to print a native process.
13648            if (args != null && args.length > opti
13649                    && args[opti].charAt(0) != '-') {
13650                ArrayList<ProcessCpuTracker.Stats> nativeProcs
13651                        = new ArrayList<ProcessCpuTracker.Stats>();
13652                updateCpuStatsNow();
13653                int findPid = -1;
13654                try {
13655                    findPid = Integer.parseInt(args[opti]);
13656                } catch (NumberFormatException e) {
13657                }
13658                synchronized (mProcessCpuThread) {
13659                    final int N = mProcessCpuTracker.countStats();
13660                    for (int i=0; i<N; i++) {
13661                        ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13662                        if (st.pid == findPid || (st.baseName != null
13663                                && st.baseName.equals(args[opti]))) {
13664                            nativeProcs.add(st);
13665                        }
13666                    }
13667                }
13668                if (nativeProcs.size() > 0) {
13669                    dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
13670                            isCompact);
13671                    Debug.MemoryInfo mi = null;
13672                    for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
13673                        final ProcessCpuTracker.Stats r = nativeProcs.get(i);
13674                        final int pid = r.pid;
13675                        if (!isCheckinRequest && dumpDetails) {
13676                            pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
13677                        }
13678                        if (mi == null) {
13679                            mi = new Debug.MemoryInfo();
13680                        }
13681                        if (dumpDetails || (!brief && !oomOnly)) {
13682                            Debug.getMemoryInfo(pid, mi);
13683                        } else {
13684                            mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13685                            mi.dalvikPrivateDirty = (int)tmpLong[0];
13686                        }
13687                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13688                                dumpDalvik, pid, r.baseName, 0, 0, 0, 0, 0, 0);
13689                        if (isCheckinRequest) {
13690                            pw.println();
13691                        }
13692                    }
13693                    return;
13694                }
13695            }
13696            pw.println("No process found for: " + args[opti]);
13697            return;
13698        }
13699
13700        if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest)) {
13701            dumpDetails = true;
13702        }
13703
13704        dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
13705
13706        String[] innerArgs = new String[args.length-opti];
13707        System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
13708
13709        ArrayList<MemItem> procMems = new ArrayList<MemItem>();
13710        final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
13711        long nativePss=0, dalvikPss=0, otherPss=0;
13712        long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
13713
13714        long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
13715        ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
13716                new ArrayList[DUMP_MEM_OOM_LABEL.length];
13717
13718        long totalPss = 0;
13719        long cachedPss = 0;
13720
13721        Debug.MemoryInfo mi = null;
13722        for (int i = procs.size() - 1 ; i >= 0 ; i--) {
13723            final ProcessRecord r = procs.get(i);
13724            final IApplicationThread thread;
13725            final int pid;
13726            final int oomAdj;
13727            final boolean hasActivities;
13728            synchronized (this) {
13729                thread = r.thread;
13730                pid = r.pid;
13731                oomAdj = r.getSetAdjWithServices();
13732                hasActivities = r.activities.size() > 0;
13733            }
13734            if (thread != null) {
13735                if (!isCheckinRequest && dumpDetails) {
13736                    pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
13737                }
13738                if (mi == null) {
13739                    mi = new Debug.MemoryInfo();
13740                }
13741                if (dumpDetails || (!brief && !oomOnly)) {
13742                    Debug.getMemoryInfo(pid, mi);
13743                } else {
13744                    mi.dalvikPss = (int)Debug.getPss(pid, tmpLong);
13745                    mi.dalvikPrivateDirty = (int)tmpLong[0];
13746                }
13747                if (dumpDetails) {
13748                    if (localOnly) {
13749                        ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
13750                                dumpDalvik, pid, r.processName, 0, 0, 0, 0, 0, 0);
13751                        if (isCheckinRequest) {
13752                            pw.println();
13753                        }
13754                    } else {
13755                        try {
13756                            pw.flush();
13757                            thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
13758                                    dumpDalvik, innerArgs);
13759                        } catch (RemoteException e) {
13760                            if (!isCheckinRequest) {
13761                                pw.println("Got RemoteException!");
13762                                pw.flush();
13763                            }
13764                        }
13765                    }
13766                }
13767
13768                final long myTotalPss = mi.getTotalPss();
13769                final long myTotalUss = mi.getTotalUss();
13770
13771                synchronized (this) {
13772                    if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
13773                        // Record this for posterity if the process has been stable.
13774                        r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
13775                    }
13776                }
13777
13778                if (!isCheckinRequest && mi != null) {
13779                    totalPss += myTotalPss;
13780                    MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
13781                            (hasActivities ? " / activities)" : ")"),
13782                            r.processName, myTotalPss, pid, hasActivities);
13783                    procMems.add(pssItem);
13784                    procMemsMap.put(pid, pssItem);
13785
13786                    nativePss += mi.nativePss;
13787                    dalvikPss += mi.dalvikPss;
13788                    otherPss += mi.otherPss;
13789                    for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13790                        long mem = mi.getOtherPss(j);
13791                        miscPss[j] += mem;
13792                        otherPss -= mem;
13793                    }
13794
13795                    if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
13796                        cachedPss += myTotalPss;
13797                    }
13798
13799                    for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
13800                        if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
13801                                || oomIndex == (oomPss.length-1)) {
13802                            oomPss[oomIndex] += myTotalPss;
13803                            if (oomProcs[oomIndex] == null) {
13804                                oomProcs[oomIndex] = new ArrayList<MemItem>();
13805                            }
13806                            oomProcs[oomIndex].add(pssItem);
13807                            break;
13808                        }
13809                    }
13810                }
13811            }
13812        }
13813
13814        long nativeProcTotalPss = 0;
13815
13816        if (!isCheckinRequest && procs.size() > 1) {
13817            // If we are showing aggregations, also look for native processes to
13818            // include so that our aggregations are more accurate.
13819            updateCpuStatsNow();
13820            synchronized (mProcessCpuThread) {
13821                final int N = mProcessCpuTracker.countStats();
13822                for (int i=0; i<N; i++) {
13823                    ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
13824                    if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
13825                        if (mi == null) {
13826                            mi = new Debug.MemoryInfo();
13827                        }
13828                        if (!brief && !oomOnly) {
13829                            Debug.getMemoryInfo(st.pid, mi);
13830                        } else {
13831                            mi.nativePss = (int)Debug.getPss(st.pid, tmpLong);
13832                            mi.nativePrivateDirty = (int)tmpLong[0];
13833                        }
13834
13835                        final long myTotalPss = mi.getTotalPss();
13836                        totalPss += myTotalPss;
13837                        nativeProcTotalPss += myTotalPss;
13838
13839                        MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
13840                                st.name, myTotalPss, st.pid, false);
13841                        procMems.add(pssItem);
13842
13843                        nativePss += mi.nativePss;
13844                        dalvikPss += mi.dalvikPss;
13845                        otherPss += mi.otherPss;
13846                        for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13847                            long mem = mi.getOtherPss(j);
13848                            miscPss[j] += mem;
13849                            otherPss -= mem;
13850                        }
13851                        oomPss[0] += myTotalPss;
13852                        if (oomProcs[0] == null) {
13853                            oomProcs[0] = new ArrayList<MemItem>();
13854                        }
13855                        oomProcs[0].add(pssItem);
13856                    }
13857                }
13858            }
13859
13860            ArrayList<MemItem> catMems = new ArrayList<MemItem>();
13861
13862            catMems.add(new MemItem("Native", "Native", nativePss, -1));
13863            catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
13864            catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
13865            for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
13866                String label = Debug.MemoryInfo.getOtherLabel(j);
13867                catMems.add(new MemItem(label, label, miscPss[j], j));
13868            }
13869
13870            ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
13871            for (int j=0; j<oomPss.length; j++) {
13872                if (oomPss[j] != 0) {
13873                    String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
13874                            : DUMP_MEM_OOM_LABEL[j];
13875                    MemItem item = new MemItem(label, label, oomPss[j],
13876                            DUMP_MEM_OOM_ADJ[j]);
13877                    item.subitems = oomProcs[j];
13878                    oomMems.add(item);
13879                }
13880            }
13881
13882            if (!brief && !oomOnly && !isCompact) {
13883                pw.println();
13884                pw.println("Total PSS by process:");
13885                dumpMemItems(pw, "  ", "proc", procMems, true, isCompact);
13886                pw.println();
13887            }
13888            if (!isCompact) {
13889                pw.println("Total PSS by OOM adjustment:");
13890            }
13891            dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact);
13892            if (!brief && !oomOnly) {
13893                PrintWriter out = categoryPw != null ? categoryPw : pw;
13894                if (!isCompact) {
13895                    out.println();
13896                    out.println("Total PSS by category:");
13897                }
13898                dumpMemItems(out, "  ", "cat", catMems, true, isCompact);
13899            }
13900            if (!isCompact) {
13901                pw.println();
13902            }
13903            MemInfoReader memInfo = new MemInfoReader();
13904            memInfo.readMemInfo();
13905            if (nativeProcTotalPss > 0) {
13906                synchronized (this) {
13907                    mProcessStats.addSysMemUsageLocked(memInfo.getCachedSizeKb(),
13908                            memInfo.getFreeSizeKb(), memInfo.getZramTotalSizeKb(),
13909                            memInfo.getBuffersSizeKb()+memInfo.getShmemSizeKb()+memInfo.getSlabSizeKb(),
13910                            nativeProcTotalPss);
13911                }
13912            }
13913            if (!brief) {
13914                if (!isCompact) {
13915                    pw.print("Total RAM: "); pw.print(memInfo.getTotalSizeKb());
13916                    pw.print(" kB (status ");
13917                    switch (mLastMemoryLevel) {
13918                        case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
13919                            pw.println("normal)");
13920                            break;
13921                        case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
13922                            pw.println("moderate)");
13923                            break;
13924                        case ProcessStats.ADJ_MEM_FACTOR_LOW:
13925                            pw.println("low)");
13926                            break;
13927                        case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
13928                            pw.println("critical)");
13929                            break;
13930                        default:
13931                            pw.print(mLastMemoryLevel);
13932                            pw.println(")");
13933                            break;
13934                    }
13935                    pw.print(" Free RAM: "); pw.print(cachedPss + memInfo.getCachedSizeKb()
13936                            + memInfo.getFreeSizeKb()); pw.print(" kB (");
13937                            pw.print(cachedPss); pw.print(" cached pss + ");
13938                            pw.print(memInfo.getCachedSizeKb()); pw.print(" cached + ");
13939                            pw.print(memInfo.getFreeSizeKb()); pw.println(" free)");
13940                } else {
13941                    pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
13942                    pw.print(cachedPss + memInfo.getCachedSizeKb()
13943                            + memInfo.getFreeSizeKb()); pw.print(",");
13944                    pw.println(totalPss - cachedPss);
13945                }
13946            }
13947            if (!isCompact) {
13948                pw.print(" Used RAM: "); pw.print(totalPss - cachedPss
13949                        + memInfo.getBuffersSizeKb() + memInfo.getShmemSizeKb()
13950                        + memInfo.getSlabSizeKb()); pw.print(" kB (");
13951                        pw.print(totalPss - cachedPss); pw.print(" used pss + ");
13952                        pw.print(memInfo.getBuffersSizeKb()); pw.print(" buffers + ");
13953                        pw.print(memInfo.getShmemSizeKb()); pw.print(" shmem + ");
13954                        pw.print(memInfo.getSlabSizeKb()); pw.println(" slab)");
13955                pw.print(" Lost RAM: "); pw.print(memInfo.getTotalSizeKb()
13956                        - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
13957                        - memInfo.getBuffersSizeKb() - memInfo.getShmemSizeKb()
13958                        - memInfo.getSlabSizeKb()); pw.println(" kB");
13959            }
13960            if (!brief) {
13961                if (memInfo.getZramTotalSizeKb() != 0) {
13962                    if (!isCompact) {
13963                        pw.print("     ZRAM: "); pw.print(memInfo.getZramTotalSizeKb());
13964                                pw.print(" kB physical used for ");
13965                                pw.print(memInfo.getSwapTotalSizeKb()
13966                                        - memInfo.getSwapFreeSizeKb());
13967                                pw.print(" kB in swap (");
13968                                pw.print(memInfo.getSwapTotalSizeKb());
13969                                pw.println(" kB total swap)");
13970                    } else {
13971                        pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
13972                                pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
13973                                pw.println(memInfo.getSwapFreeSizeKb());
13974                    }
13975                }
13976                final int[] SINGLE_LONG_FORMAT = new int[] {
13977                    Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
13978                };
13979                long[] longOut = new long[1];
13980                Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
13981                        SINGLE_LONG_FORMAT, null, longOut, null);
13982                long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13983                longOut[0] = 0;
13984                Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
13985                        SINGLE_LONG_FORMAT, null, longOut, null);
13986                long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13987                longOut[0] = 0;
13988                Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
13989                        SINGLE_LONG_FORMAT, null, longOut, null);
13990                long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13991                longOut[0] = 0;
13992                Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
13993                        SINGLE_LONG_FORMAT, null, longOut, null);
13994                long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
13995                if (!isCompact) {
13996                    if (sharing != 0 || shared != 0 || unshared != 0 || voltile != 0) {
13997                        pw.print("      KSM: "); pw.print(sharing);
13998                                pw.print(" kB saved from shared ");
13999                                pw.print(shared); pw.println(" kB");
14000                        pw.print("           "); pw.print(unshared); pw.print(" kB unshared; ");
14001                                pw.print(voltile); pw.println(" kB volatile");
14002                    }
14003                    pw.print("   Tuning: ");
14004                    pw.print(ActivityManager.staticGetMemoryClass());
14005                    pw.print(" (large ");
14006                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14007                    pw.print("), oom ");
14008                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14009                    pw.print(" kB");
14010                    pw.print(", restore limit ");
14011                    pw.print(mProcessList.getCachedRestoreThresholdKb());
14012                    pw.print(" kB");
14013                    if (ActivityManager.isLowRamDeviceStatic()) {
14014                        pw.print(" (low-ram)");
14015                    }
14016                    if (ActivityManager.isHighEndGfx()) {
14017                        pw.print(" (high-end-gfx)");
14018                    }
14019                    pw.println();
14020                } else {
14021                    pw.print("ksm,"); pw.print(sharing); pw.print(",");
14022                    pw.print(shared); pw.print(","); pw.print(unshared); pw.print(",");
14023                    pw.println(voltile);
14024                    pw.print("tuning,");
14025                    pw.print(ActivityManager.staticGetMemoryClass());
14026                    pw.print(',');
14027                    pw.print(ActivityManager.staticGetLargeMemoryClass());
14028                    pw.print(',');
14029                    pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
14030                    if (ActivityManager.isLowRamDeviceStatic()) {
14031                        pw.print(",low-ram");
14032                    }
14033                    if (ActivityManager.isHighEndGfx()) {
14034                        pw.print(",high-end-gfx");
14035                    }
14036                    pw.println();
14037                }
14038            }
14039        }
14040    }
14041
14042    /**
14043     * Searches array of arguments for the specified string
14044     * @param args array of argument strings
14045     * @param value value to search for
14046     * @return true if the value is contained in the array
14047     */
14048    private static boolean scanArgs(String[] args, String value) {
14049        if (args != null) {
14050            for (String arg : args) {
14051                if (value.equals(arg)) {
14052                    return true;
14053                }
14054            }
14055        }
14056        return false;
14057    }
14058
14059    private final boolean removeDyingProviderLocked(ProcessRecord proc,
14060            ContentProviderRecord cpr, boolean always) {
14061        final boolean inLaunching = mLaunchingProviders.contains(cpr);
14062
14063        if (!inLaunching || always) {
14064            synchronized (cpr) {
14065                cpr.launchingApp = null;
14066                cpr.notifyAll();
14067            }
14068            mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
14069            String names[] = cpr.info.authority.split(";");
14070            for (int j = 0; j < names.length; j++) {
14071                mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
14072            }
14073        }
14074
14075        for (int i=0; i<cpr.connections.size(); i++) {
14076            ContentProviderConnection conn = cpr.connections.get(i);
14077            if (conn.waiting) {
14078                // If this connection is waiting for the provider, then we don't
14079                // need to mess with its process unless we are always removing
14080                // or for some reason the provider is not currently launching.
14081                if (inLaunching && !always) {
14082                    continue;
14083                }
14084            }
14085            ProcessRecord capp = conn.client;
14086            conn.dead = true;
14087            if (conn.stableCount > 0) {
14088                if (!capp.persistent && capp.thread != null
14089                        && capp.pid != 0
14090                        && capp.pid != MY_PID) {
14091                    capp.kill("depends on provider "
14092                            + cpr.name.flattenToShortString()
14093                            + " in dying proc " + (proc != null ? proc.processName : "??"), true);
14094                }
14095            } else if (capp.thread != null && conn.provider.provider != null) {
14096                try {
14097                    capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
14098                } catch (RemoteException e) {
14099                }
14100                // In the protocol here, we don't expect the client to correctly
14101                // clean up this connection, we'll just remove it.
14102                cpr.connections.remove(i);
14103                conn.client.conProviders.remove(conn);
14104            }
14105        }
14106
14107        if (inLaunching && always) {
14108            mLaunchingProviders.remove(cpr);
14109        }
14110        return inLaunching;
14111    }
14112
14113    /**
14114     * Main code for cleaning up a process when it has gone away.  This is
14115     * called both as a result of the process dying, or directly when stopping
14116     * a process when running in single process mode.
14117     */
14118    private final void cleanUpApplicationRecordLocked(ProcessRecord app,
14119            boolean restarting, boolean allowRestart, int index) {
14120        if (index >= 0) {
14121            removeLruProcessLocked(app);
14122            ProcessList.remove(app.pid);
14123        }
14124
14125        mProcessesToGc.remove(app);
14126        mPendingPssProcesses.remove(app);
14127
14128        // Dismiss any open dialogs.
14129        if (app.crashDialog != null && !app.forceCrashReport) {
14130            app.crashDialog.dismiss();
14131            app.crashDialog = null;
14132        }
14133        if (app.anrDialog != null) {
14134            app.anrDialog.dismiss();
14135            app.anrDialog = null;
14136        }
14137        if (app.waitDialog != null) {
14138            app.waitDialog.dismiss();
14139            app.waitDialog = null;
14140        }
14141
14142        app.crashing = false;
14143        app.notResponding = false;
14144
14145        app.resetPackageList(mProcessStats);
14146        app.unlinkDeathRecipient();
14147        app.makeInactive(mProcessStats);
14148        app.waitingToKill = null;
14149        app.forcingToForeground = null;
14150        updateProcessForegroundLocked(app, false, false);
14151        app.foregroundActivities = false;
14152        app.hasShownUi = false;
14153        app.treatLikeActivity = false;
14154        app.hasAboveClient = false;
14155        app.hasClientActivities = false;
14156
14157        mServices.killServicesLocked(app, allowRestart);
14158
14159        boolean restart = false;
14160
14161        // Remove published content providers.
14162        for (int i=app.pubProviders.size()-1; i>=0; i--) {
14163            ContentProviderRecord cpr = app.pubProviders.valueAt(i);
14164            final boolean always = app.bad || !allowRestart;
14165            if (removeDyingProviderLocked(app, cpr, always) || always) {
14166                // We left the provider in the launching list, need to
14167                // restart it.
14168                restart = true;
14169            }
14170
14171            cpr.provider = null;
14172            cpr.proc = null;
14173        }
14174        app.pubProviders.clear();
14175
14176        // Take care of any launching providers waiting for this process.
14177        if (checkAppInLaunchingProvidersLocked(app, false)) {
14178            restart = true;
14179        }
14180
14181        // Unregister from connected content providers.
14182        if (!app.conProviders.isEmpty()) {
14183            for (int i=0; i<app.conProviders.size(); i++) {
14184                ContentProviderConnection conn = app.conProviders.get(i);
14185                conn.provider.connections.remove(conn);
14186            }
14187            app.conProviders.clear();
14188        }
14189
14190        // At this point there may be remaining entries in mLaunchingProviders
14191        // where we were the only one waiting, so they are no longer of use.
14192        // Look for these and clean up if found.
14193        // XXX Commented out for now.  Trying to figure out a way to reproduce
14194        // the actual situation to identify what is actually going on.
14195        if (false) {
14196            for (int i=0; i<mLaunchingProviders.size(); i++) {
14197                ContentProviderRecord cpr = (ContentProviderRecord)
14198                        mLaunchingProviders.get(i);
14199                if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
14200                    synchronized (cpr) {
14201                        cpr.launchingApp = null;
14202                        cpr.notifyAll();
14203                    }
14204                }
14205            }
14206        }
14207
14208        skipCurrentReceiverLocked(app);
14209
14210        // Unregister any receivers.
14211        for (int i=app.receivers.size()-1; i>=0; i--) {
14212            removeReceiverLocked(app.receivers.valueAt(i));
14213        }
14214        app.receivers.clear();
14215
14216        // If the app is undergoing backup, tell the backup manager about it
14217        if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
14218            if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
14219                    + mBackupTarget.appInfo + " died during backup");
14220            try {
14221                IBackupManager bm = IBackupManager.Stub.asInterface(
14222                        ServiceManager.getService(Context.BACKUP_SERVICE));
14223                bm.agentDisconnected(app.info.packageName);
14224            } catch (RemoteException e) {
14225                // can't happen; backup manager is local
14226            }
14227        }
14228
14229        for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
14230            ProcessChangeItem item = mPendingProcessChanges.get(i);
14231            if (item.pid == app.pid) {
14232                mPendingProcessChanges.remove(i);
14233                mAvailProcessChanges.add(item);
14234            }
14235        }
14236        mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
14237
14238        // If the caller is restarting this app, then leave it in its
14239        // current lists and let the caller take care of it.
14240        if (restarting) {
14241            return;
14242        }
14243
14244        if (!app.persistent || app.isolated) {
14245            if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
14246                    "Removing non-persistent process during cleanup: " + app);
14247            mProcessNames.remove(app.processName, app.uid);
14248            mIsolatedProcesses.remove(app.uid);
14249            if (mHeavyWeightProcess == app) {
14250                mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
14251                        mHeavyWeightProcess.userId, 0));
14252                mHeavyWeightProcess = null;
14253            }
14254        } else if (!app.removed) {
14255            // This app is persistent, so we need to keep its record around.
14256            // If it is not already on the pending app list, add it there
14257            // and start a new process for it.
14258            if (mPersistentStartingProcesses.indexOf(app) < 0) {
14259                mPersistentStartingProcesses.add(app);
14260                restart = true;
14261            }
14262        }
14263        if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
14264                "Clean-up removing on hold: " + app);
14265        mProcessesOnHold.remove(app);
14266
14267        if (app == mHomeProcess) {
14268            mHomeProcess = null;
14269        }
14270        if (app == mPreviousProcess) {
14271            mPreviousProcess = null;
14272        }
14273
14274        if (restart && !app.isolated) {
14275            // We have components that still need to be running in the
14276            // process, so re-launch it.
14277            mProcessNames.put(app.processName, app.uid, app);
14278            startProcessLocked(app, "restart", app.processName);
14279        } else if (app.pid > 0 && app.pid != MY_PID) {
14280            // Goodbye!
14281            boolean removed;
14282            synchronized (mPidsSelfLocked) {
14283                mPidsSelfLocked.remove(app.pid);
14284                mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
14285            }
14286            mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
14287            if (app.isolated) {
14288                mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
14289            }
14290            app.setPid(0);
14291        }
14292    }
14293
14294    boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
14295        // Look through the content providers we are waiting to have launched,
14296        // and if any run in this process then either schedule a restart of
14297        // the process or kill the client waiting for it if this process has
14298        // gone bad.
14299        int NL = mLaunchingProviders.size();
14300        boolean restart = false;
14301        for (int i=0; i<NL; i++) {
14302            ContentProviderRecord cpr = mLaunchingProviders.get(i);
14303            if (cpr.launchingApp == app) {
14304                if (!alwaysBad && !app.bad) {
14305                    restart = true;
14306                } else {
14307                    removeDyingProviderLocked(app, cpr, true);
14308                    // cpr should have been removed from mLaunchingProviders
14309                    NL = mLaunchingProviders.size();
14310                    i--;
14311                }
14312            }
14313        }
14314        return restart;
14315    }
14316
14317    // =========================================================
14318    // SERVICES
14319    // =========================================================
14320
14321    @Override
14322    public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
14323            int flags) {
14324        enforceNotIsolatedCaller("getServices");
14325        synchronized (this) {
14326            return mServices.getRunningServiceInfoLocked(maxNum, flags);
14327        }
14328    }
14329
14330    @Override
14331    public PendingIntent getRunningServiceControlPanel(ComponentName name) {
14332        enforceNotIsolatedCaller("getRunningServiceControlPanel");
14333        synchronized (this) {
14334            return mServices.getRunningServiceControlPanelLocked(name);
14335        }
14336    }
14337
14338    @Override
14339    public ComponentName startService(IApplicationThread caller, Intent service,
14340            String resolvedType, int userId) {
14341        enforceNotIsolatedCaller("startService");
14342        // Refuse possible leaked file descriptors
14343        if (service != null && service.hasFileDescriptors() == true) {
14344            throw new IllegalArgumentException("File descriptors passed in Intent");
14345        }
14346
14347        if (DEBUG_SERVICE)
14348            Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
14349        synchronized(this) {
14350            final int callingPid = Binder.getCallingPid();
14351            final int callingUid = Binder.getCallingUid();
14352            final long origId = Binder.clearCallingIdentity();
14353            ComponentName res = mServices.startServiceLocked(caller, service,
14354                    resolvedType, callingPid, callingUid, userId);
14355            Binder.restoreCallingIdentity(origId);
14356            return res;
14357        }
14358    }
14359
14360    ComponentName startServiceInPackage(int uid,
14361            Intent service, String resolvedType, int userId) {
14362        synchronized(this) {
14363            if (DEBUG_SERVICE)
14364                Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
14365            final long origId = Binder.clearCallingIdentity();
14366            ComponentName res = mServices.startServiceLocked(null, service,
14367                    resolvedType, -1, uid, userId);
14368            Binder.restoreCallingIdentity(origId);
14369            return res;
14370        }
14371    }
14372
14373    @Override
14374    public int stopService(IApplicationThread caller, Intent service,
14375            String resolvedType, int userId) {
14376        enforceNotIsolatedCaller("stopService");
14377        // Refuse possible leaked file descriptors
14378        if (service != null && service.hasFileDescriptors() == true) {
14379            throw new IllegalArgumentException("File descriptors passed in Intent");
14380        }
14381
14382        synchronized(this) {
14383            return mServices.stopServiceLocked(caller, service, resolvedType, userId);
14384        }
14385    }
14386
14387    @Override
14388    public IBinder peekService(Intent service, String resolvedType) {
14389        enforceNotIsolatedCaller("peekService");
14390        // Refuse possible leaked file descriptors
14391        if (service != null && service.hasFileDescriptors() == true) {
14392            throw new IllegalArgumentException("File descriptors passed in Intent");
14393        }
14394        synchronized(this) {
14395            return mServices.peekServiceLocked(service, resolvedType);
14396        }
14397    }
14398
14399    @Override
14400    public boolean stopServiceToken(ComponentName className, IBinder token,
14401            int startId) {
14402        synchronized(this) {
14403            return mServices.stopServiceTokenLocked(className, token, startId);
14404        }
14405    }
14406
14407    @Override
14408    public void setServiceForeground(ComponentName className, IBinder token,
14409            int id, Notification notification, boolean removeNotification) {
14410        synchronized(this) {
14411            mServices.setServiceForegroundLocked(className, token, id, notification,
14412                    removeNotification);
14413        }
14414    }
14415
14416    @Override
14417    public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14418            boolean requireFull, String name, String callerPackage) {
14419        return handleIncomingUser(callingPid, callingUid, userId, allowAll,
14420                requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
14421    }
14422
14423    int unsafeConvertIncomingUser(int userId) {
14424        return (userId == UserHandle.USER_CURRENT || userId == UserHandle.USER_CURRENT_OR_SELF)
14425                ? mCurrentUserId : userId;
14426    }
14427
14428    int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
14429            int allowMode, String name, String callerPackage) {
14430        final int callingUserId = UserHandle.getUserId(callingUid);
14431        if (callingUserId == userId) {
14432            return userId;
14433        }
14434
14435        // Note that we may be accessing mCurrentUserId outside of a lock...
14436        // shouldn't be a big deal, if this is being called outside
14437        // of a locked context there is intrinsically a race with
14438        // the value the caller will receive and someone else changing it.
14439        // We assume that USER_CURRENT_OR_SELF will use the current user; later
14440        // we will switch to the calling user if access to the current user fails.
14441        int targetUserId = unsafeConvertIncomingUser(userId);
14442
14443        if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
14444            final boolean allow;
14445            if (checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
14446                    callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
14447                // If the caller has this permission, they always pass go.  And collect $200.
14448                allow = true;
14449            } else if (allowMode == ALLOW_FULL_ONLY) {
14450                // We require full access, sucks to be you.
14451                allow = false;
14452            } else if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
14453                    callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
14454                // If the caller does not have either permission, they are always doomed.
14455                allow = false;
14456            } else if (allowMode == ALLOW_NON_FULL) {
14457                // We are blanket allowing non-full access, you lucky caller!
14458                allow = true;
14459            } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE) {
14460                // We may or may not allow this depending on whether the two users are
14461                // in the same profile.
14462                synchronized (mUserProfileGroupIdsSelfLocked) {
14463                    int callingProfile = mUserProfileGroupIdsSelfLocked.get(callingUserId,
14464                            UserInfo.NO_PROFILE_GROUP_ID);
14465                    int targetProfile = mUserProfileGroupIdsSelfLocked.get(targetUserId,
14466                            UserInfo.NO_PROFILE_GROUP_ID);
14467                    allow = callingProfile != UserInfo.NO_PROFILE_GROUP_ID
14468                            && callingProfile == targetProfile;
14469                }
14470            } else {
14471                throw new IllegalArgumentException("Unknown mode: " + allowMode);
14472            }
14473            if (!allow) {
14474                if (userId == UserHandle.USER_CURRENT_OR_SELF) {
14475                    // In this case, they would like to just execute as their
14476                    // owner user instead of failing.
14477                    targetUserId = callingUserId;
14478                } else {
14479                    StringBuilder builder = new StringBuilder(128);
14480                    builder.append("Permission Denial: ");
14481                    builder.append(name);
14482                    if (callerPackage != null) {
14483                        builder.append(" from ");
14484                        builder.append(callerPackage);
14485                    }
14486                    builder.append(" asks to run as user ");
14487                    builder.append(userId);
14488                    builder.append(" but is calling from user ");
14489                    builder.append(UserHandle.getUserId(callingUid));
14490                    builder.append("; this requires ");
14491                    builder.append(INTERACT_ACROSS_USERS_FULL);
14492                    if (allowMode != ALLOW_FULL_ONLY) {
14493                        builder.append(" or ");
14494                        builder.append(INTERACT_ACROSS_USERS);
14495                    }
14496                    String msg = builder.toString();
14497                    Slog.w(TAG, msg);
14498                    throw new SecurityException(msg);
14499                }
14500            }
14501        }
14502        if (!allowAll && targetUserId < 0) {
14503            throw new IllegalArgumentException(
14504                    "Call does not support special user #" + targetUserId);
14505        }
14506        return targetUserId;
14507    }
14508
14509    boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
14510            String className, int flags) {
14511        boolean result = false;
14512        // For apps that don't have pre-defined UIDs, check for permission
14513        if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
14514            if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14515                if (ActivityManager.checkUidPermission(
14516                        INTERACT_ACROSS_USERS,
14517                        aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
14518                    ComponentName comp = new ComponentName(aInfo.packageName, className);
14519                    String msg = "Permission Denial: Component " + comp.flattenToShortString()
14520                            + " requests FLAG_SINGLE_USER, but app does not hold "
14521                            + INTERACT_ACROSS_USERS;
14522                    Slog.w(TAG, msg);
14523                    throw new SecurityException(msg);
14524                }
14525                // Permission passed
14526                result = true;
14527            }
14528        } else if ("system".equals(componentProcessName)) {
14529            result = true;
14530        } else if (UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
14531                && (flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
14532            // Phone app is allowed to export singleuser providers.
14533            result = true;
14534        } else {
14535            // App with pre-defined UID, check if it's a persistent app
14536            result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
14537        }
14538        if (DEBUG_MU) {
14539            Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
14540                    + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
14541        }
14542        return result;
14543    }
14544
14545    /**
14546     * Checks to see if the caller is in the same app as the singleton
14547     * component, or the component is in a special app. It allows special apps
14548     * to export singleton components but prevents exporting singleton
14549     * components for regular apps.
14550     */
14551    boolean isValidSingletonCall(int callingUid, int componentUid) {
14552        int componentAppId = UserHandle.getAppId(componentUid);
14553        return UserHandle.isSameApp(callingUid, componentUid)
14554                || componentAppId == Process.SYSTEM_UID
14555                || componentAppId == Process.PHONE_UID
14556                || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
14557                        == PackageManager.PERMISSION_GRANTED;
14558    }
14559
14560    public int bindService(IApplicationThread caller, IBinder token,
14561            Intent service, String resolvedType,
14562            IServiceConnection connection, int flags, int userId) {
14563        enforceNotIsolatedCaller("bindService");
14564        // Refuse possible leaked file descriptors
14565        if (service != null && service.hasFileDescriptors() == true) {
14566            throw new IllegalArgumentException("File descriptors passed in Intent");
14567        }
14568
14569        synchronized(this) {
14570            return mServices.bindServiceLocked(caller, token, service, resolvedType,
14571                    connection, flags, userId);
14572        }
14573    }
14574
14575    public boolean unbindService(IServiceConnection connection) {
14576        synchronized (this) {
14577            return mServices.unbindServiceLocked(connection);
14578        }
14579    }
14580
14581    public void publishService(IBinder token, Intent intent, IBinder service) {
14582        // Refuse possible leaked file descriptors
14583        if (intent != null && intent.hasFileDescriptors() == true) {
14584            throw new IllegalArgumentException("File descriptors passed in Intent");
14585        }
14586
14587        synchronized(this) {
14588            if (!(token instanceof ServiceRecord)) {
14589                throw new IllegalArgumentException("Invalid service token");
14590            }
14591            mServices.publishServiceLocked((ServiceRecord)token, intent, service);
14592        }
14593    }
14594
14595    public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
14596        // Refuse possible leaked file descriptors
14597        if (intent != null && intent.hasFileDescriptors() == true) {
14598            throw new IllegalArgumentException("File descriptors passed in Intent");
14599        }
14600
14601        synchronized(this) {
14602            mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
14603        }
14604    }
14605
14606    public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
14607        synchronized(this) {
14608            if (!(token instanceof ServiceRecord)) {
14609                throw new IllegalArgumentException("Invalid service token");
14610            }
14611            mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
14612        }
14613    }
14614
14615    // =========================================================
14616    // BACKUP AND RESTORE
14617    // =========================================================
14618
14619    // Cause the target app to be launched if necessary and its backup agent
14620    // instantiated.  The backup agent will invoke backupAgentCreated() on the
14621    // activity manager to announce its creation.
14622    public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
14623        if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
14624        enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
14625
14626        synchronized(this) {
14627            // !!! TODO: currently no check here that we're already bound
14628            BatteryStatsImpl.Uid.Pkg.Serv ss = null;
14629            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14630            synchronized (stats) {
14631                ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
14632            }
14633
14634            // Backup agent is now in use, its package can't be stopped.
14635            try {
14636                AppGlobals.getPackageManager().setPackageStoppedState(
14637                        app.packageName, false, UserHandle.getUserId(app.uid));
14638            } catch (RemoteException e) {
14639            } catch (IllegalArgumentException e) {
14640                Slog.w(TAG, "Failed trying to unstop package "
14641                        + app.packageName + ": " + e);
14642            }
14643
14644            BackupRecord r = new BackupRecord(ss, app, backupMode);
14645            ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
14646                    ? new ComponentName(app.packageName, app.backupAgentName)
14647                    : new ComponentName("android", "FullBackupAgent");
14648            // startProcessLocked() returns existing proc's record if it's already running
14649            ProcessRecord proc = startProcessLocked(app.processName, app,
14650                    false, 0, "backup", hostingName, false, false, false);
14651            if (proc == null) {
14652                Slog.e(TAG, "Unable to start backup agent process " + r);
14653                return false;
14654            }
14655
14656            r.app = proc;
14657            mBackupTarget = r;
14658            mBackupAppName = app.packageName;
14659
14660            // Try not to kill the process during backup
14661            updateOomAdjLocked(proc);
14662
14663            // If the process is already attached, schedule the creation of the backup agent now.
14664            // If it is not yet live, this will be done when it attaches to the framework.
14665            if (proc.thread != null) {
14666                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
14667                try {
14668                    proc.thread.scheduleCreateBackupAgent(app,
14669                            compatibilityInfoForPackageLocked(app), backupMode);
14670                } catch (RemoteException e) {
14671                    // Will time out on the backup manager side
14672                }
14673            } else {
14674                if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
14675            }
14676            // Invariants: at this point, the target app process exists and the application
14677            // is either already running or in the process of coming up.  mBackupTarget and
14678            // mBackupAppName describe the app, so that when it binds back to the AM we
14679            // know that it's scheduled for a backup-agent operation.
14680        }
14681
14682        return true;
14683    }
14684
14685    @Override
14686    public void clearPendingBackup() {
14687        if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
14688        enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
14689
14690        synchronized (this) {
14691            mBackupTarget = null;
14692            mBackupAppName = null;
14693        }
14694    }
14695
14696    // A backup agent has just come up
14697    public void backupAgentCreated(String agentPackageName, IBinder agent) {
14698        if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
14699                + " = " + agent);
14700
14701        synchronized(this) {
14702            if (!agentPackageName.equals(mBackupAppName)) {
14703                Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
14704                return;
14705            }
14706        }
14707
14708        long oldIdent = Binder.clearCallingIdentity();
14709        try {
14710            IBackupManager bm = IBackupManager.Stub.asInterface(
14711                    ServiceManager.getService(Context.BACKUP_SERVICE));
14712            bm.agentConnected(agentPackageName, agent);
14713        } catch (RemoteException e) {
14714            // can't happen; the backup manager service is local
14715        } catch (Exception e) {
14716            Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
14717            e.printStackTrace();
14718        } finally {
14719            Binder.restoreCallingIdentity(oldIdent);
14720        }
14721    }
14722
14723    // done with this agent
14724    public void unbindBackupAgent(ApplicationInfo appInfo) {
14725        if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
14726        if (appInfo == null) {
14727            Slog.w(TAG, "unbind backup agent for null app");
14728            return;
14729        }
14730
14731        synchronized(this) {
14732            try {
14733                if (mBackupAppName == null) {
14734                    Slog.w(TAG, "Unbinding backup agent with no active backup");
14735                    return;
14736                }
14737
14738                if (!mBackupAppName.equals(appInfo.packageName)) {
14739                    Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
14740                    return;
14741                }
14742
14743                // Not backing this app up any more; reset its OOM adjustment
14744                final ProcessRecord proc = mBackupTarget.app;
14745                updateOomAdjLocked(proc);
14746
14747                // If the app crashed during backup, 'thread' will be null here
14748                if (proc.thread != null) {
14749                    try {
14750                        proc.thread.scheduleDestroyBackupAgent(appInfo,
14751                                compatibilityInfoForPackageLocked(appInfo));
14752                    } catch (Exception e) {
14753                        Slog.e(TAG, "Exception when unbinding backup agent:");
14754                        e.printStackTrace();
14755                    }
14756                }
14757            } finally {
14758                mBackupTarget = null;
14759                mBackupAppName = null;
14760            }
14761        }
14762    }
14763    // =========================================================
14764    // BROADCASTS
14765    // =========================================================
14766
14767    private final List getStickiesLocked(String action, IntentFilter filter,
14768            List cur, int userId) {
14769        final ContentResolver resolver = mContext.getContentResolver();
14770        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
14771        if (stickies == null) {
14772            return cur;
14773        }
14774        final ArrayList<Intent> list = stickies.get(action);
14775        if (list == null) {
14776            return cur;
14777        }
14778        int N = list.size();
14779        for (int i=0; i<N; i++) {
14780            Intent intent = list.get(i);
14781            if (filter.match(resolver, intent, true, TAG) >= 0) {
14782                if (cur == null) {
14783                    cur = new ArrayList<Intent>();
14784                }
14785                cur.add(intent);
14786            }
14787        }
14788        return cur;
14789    }
14790
14791    boolean isPendingBroadcastProcessLocked(int pid) {
14792        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
14793                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
14794    }
14795
14796    void skipPendingBroadcastLocked(int pid) {
14797            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
14798            for (BroadcastQueue queue : mBroadcastQueues) {
14799                queue.skipPendingBroadcastLocked(pid);
14800            }
14801    }
14802
14803    // The app just attached; send any pending broadcasts that it should receive
14804    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
14805        boolean didSomething = false;
14806        for (BroadcastQueue queue : mBroadcastQueues) {
14807            didSomething |= queue.sendPendingBroadcastsLocked(app);
14808        }
14809        return didSomething;
14810    }
14811
14812    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
14813            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
14814        enforceNotIsolatedCaller("registerReceiver");
14815        int callingUid;
14816        int callingPid;
14817        synchronized(this) {
14818            ProcessRecord callerApp = null;
14819            if (caller != null) {
14820                callerApp = getRecordForAppLocked(caller);
14821                if (callerApp == null) {
14822                    throw new SecurityException(
14823                            "Unable to find app for caller " + caller
14824                            + " (pid=" + Binder.getCallingPid()
14825                            + ") when registering receiver " + receiver);
14826                }
14827                if (callerApp.info.uid != Process.SYSTEM_UID &&
14828                        !callerApp.pkgList.containsKey(callerPackage) &&
14829                        !"android".equals(callerPackage)) {
14830                    throw new SecurityException("Given caller package " + callerPackage
14831                            + " is not running in process " + callerApp);
14832                }
14833                callingUid = callerApp.info.uid;
14834                callingPid = callerApp.pid;
14835            } else {
14836                callerPackage = null;
14837                callingUid = Binder.getCallingUid();
14838                callingPid = Binder.getCallingPid();
14839            }
14840
14841            userId = this.handleIncomingUser(callingPid, callingUid, userId,
14842                    true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
14843
14844            List allSticky = null;
14845
14846            // Look for any matching sticky broadcasts...
14847            Iterator actions = filter.actionsIterator();
14848            if (actions != null) {
14849                while (actions.hasNext()) {
14850                    String action = (String)actions.next();
14851                    allSticky = getStickiesLocked(action, filter, allSticky,
14852                            UserHandle.USER_ALL);
14853                    allSticky = getStickiesLocked(action, filter, allSticky,
14854                            UserHandle.getUserId(callingUid));
14855                }
14856            } else {
14857                allSticky = getStickiesLocked(null, filter, allSticky,
14858                        UserHandle.USER_ALL);
14859                allSticky = getStickiesLocked(null, filter, allSticky,
14860                        UserHandle.getUserId(callingUid));
14861            }
14862
14863            // The first sticky in the list is returned directly back to
14864            // the client.
14865            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
14866
14867            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
14868                    + ": " + sticky);
14869
14870            if (receiver == null) {
14871                return sticky;
14872            }
14873
14874            ReceiverList rl
14875                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
14876            if (rl == null) {
14877                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
14878                        userId, receiver);
14879                if (rl.app != null) {
14880                    rl.app.receivers.add(rl);
14881                } else {
14882                    try {
14883                        receiver.asBinder().linkToDeath(rl, 0);
14884                    } catch (RemoteException e) {
14885                        return sticky;
14886                    }
14887                    rl.linkedToDeath = true;
14888                }
14889                mRegisteredReceivers.put(receiver.asBinder(), rl);
14890            } else if (rl.uid != callingUid) {
14891                throw new IllegalArgumentException(
14892                        "Receiver requested to register for uid " + callingUid
14893                        + " was previously registered for uid " + rl.uid);
14894            } else if (rl.pid != callingPid) {
14895                throw new IllegalArgumentException(
14896                        "Receiver requested to register for pid " + callingPid
14897                        + " was previously registered for pid " + rl.pid);
14898            } else if (rl.userId != userId) {
14899                throw new IllegalArgumentException(
14900                        "Receiver requested to register for user " + userId
14901                        + " was previously registered for user " + rl.userId);
14902            }
14903            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
14904                    permission, callingUid, userId);
14905            rl.add(bf);
14906            if (!bf.debugCheck()) {
14907                Slog.w(TAG, "==> For Dynamic broadast");
14908            }
14909            mReceiverResolver.addFilter(bf);
14910
14911            // Enqueue broadcasts for all existing stickies that match
14912            // this filter.
14913            if (allSticky != null) {
14914                ArrayList receivers = new ArrayList();
14915                receivers.add(bf);
14916
14917                int N = allSticky.size();
14918                for (int i=0; i<N; i++) {
14919                    Intent intent = (Intent)allSticky.get(i);
14920                    BroadcastQueue queue = broadcastQueueForIntent(intent);
14921                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
14922                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
14923                            null, null, false, true, true, -1);
14924                    queue.enqueueParallelBroadcastLocked(r);
14925                    queue.scheduleBroadcastsLocked();
14926                }
14927            }
14928
14929            return sticky;
14930        }
14931    }
14932
14933    public void unregisterReceiver(IIntentReceiver receiver) {
14934        if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
14935
14936        final long origId = Binder.clearCallingIdentity();
14937        try {
14938            boolean doTrim = false;
14939
14940            synchronized(this) {
14941                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
14942                if (rl != null) {
14943                    if (rl.curBroadcast != null) {
14944                        BroadcastRecord r = rl.curBroadcast;
14945                        final boolean doNext = finishReceiverLocked(
14946                                receiver.asBinder(), r.resultCode, r.resultData,
14947                                r.resultExtras, r.resultAbort);
14948                        if (doNext) {
14949                            doTrim = true;
14950                            r.queue.processNextBroadcast(false);
14951                        }
14952                    }
14953
14954                    if (rl.app != null) {
14955                        rl.app.receivers.remove(rl);
14956                    }
14957                    removeReceiverLocked(rl);
14958                    if (rl.linkedToDeath) {
14959                        rl.linkedToDeath = false;
14960                        rl.receiver.asBinder().unlinkToDeath(rl, 0);
14961                    }
14962                }
14963            }
14964
14965            // If we actually concluded any broadcasts, we might now be able
14966            // to trim the recipients' apps from our working set
14967            if (doTrim) {
14968                trimApplications();
14969                return;
14970            }
14971
14972        } finally {
14973            Binder.restoreCallingIdentity(origId);
14974        }
14975    }
14976
14977    void removeReceiverLocked(ReceiverList rl) {
14978        mRegisteredReceivers.remove(rl.receiver.asBinder());
14979        int N = rl.size();
14980        for (int i=0; i<N; i++) {
14981            mReceiverResolver.removeFilter(rl.get(i));
14982        }
14983    }
14984
14985    private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
14986        for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14987            ProcessRecord r = mLruProcesses.get(i);
14988            if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
14989                try {
14990                    r.thread.dispatchPackageBroadcast(cmd, packages);
14991                } catch (RemoteException ex) {
14992                }
14993            }
14994        }
14995    }
14996
14997    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
14998            int[] users) {
14999        List<ResolveInfo> receivers = null;
15000        try {
15001            HashSet<ComponentName> singleUserReceivers = null;
15002            boolean scannedFirstReceivers = false;
15003            for (int user : users) {
15004                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
15005                        .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
15006                if (user != 0 && newReceivers != null) {
15007                    // If this is not the primary user, we need to check for
15008                    // any receivers that should be filtered out.
15009                    for (int i=0; i<newReceivers.size(); i++) {
15010                        ResolveInfo ri = newReceivers.get(i);
15011                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
15012                            newReceivers.remove(i);
15013                            i--;
15014                        }
15015                    }
15016                }
15017                if (newReceivers != null && newReceivers.size() == 0) {
15018                    newReceivers = null;
15019                }
15020                if (receivers == null) {
15021                    receivers = newReceivers;
15022                } else if (newReceivers != null) {
15023                    // We need to concatenate the additional receivers
15024                    // found with what we have do far.  This would be easy,
15025                    // but we also need to de-dup any receivers that are
15026                    // singleUser.
15027                    if (!scannedFirstReceivers) {
15028                        // Collect any single user receivers we had already retrieved.
15029                        scannedFirstReceivers = true;
15030                        for (int i=0; i<receivers.size(); i++) {
15031                            ResolveInfo ri = receivers.get(i);
15032                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15033                                ComponentName cn = new ComponentName(
15034                                        ri.activityInfo.packageName, ri.activityInfo.name);
15035                                if (singleUserReceivers == null) {
15036                                    singleUserReceivers = new HashSet<ComponentName>();
15037                                }
15038                                singleUserReceivers.add(cn);
15039                            }
15040                        }
15041                    }
15042                    // Add the new results to the existing results, tracking
15043                    // and de-dupping single user receivers.
15044                    for (int i=0; i<newReceivers.size(); i++) {
15045                        ResolveInfo ri = newReceivers.get(i);
15046                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
15047                            ComponentName cn = new ComponentName(
15048                                    ri.activityInfo.packageName, ri.activityInfo.name);
15049                            if (singleUserReceivers == null) {
15050                                singleUserReceivers = new HashSet<ComponentName>();
15051                            }
15052                            if (!singleUserReceivers.contains(cn)) {
15053                                singleUserReceivers.add(cn);
15054                                receivers.add(ri);
15055                            }
15056                        } else {
15057                            receivers.add(ri);
15058                        }
15059                    }
15060                }
15061            }
15062        } catch (RemoteException ex) {
15063            // pm is in same process, this will never happen.
15064        }
15065        return receivers;
15066    }
15067
15068    private final int broadcastIntentLocked(ProcessRecord callerApp,
15069            String callerPackage, Intent intent, String resolvedType,
15070            IIntentReceiver resultTo, int resultCode, String resultData,
15071            Bundle map, String requiredPermission, int appOp,
15072            boolean ordered, boolean sticky, int callingPid, int callingUid,
15073            int userId) {
15074        intent = new Intent(intent);
15075
15076        // By default broadcasts do not go to stopped apps.
15077        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
15078
15079        if (DEBUG_BROADCAST_LIGHT) Slog.v(
15080            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
15081            + " ordered=" + ordered + " userid=" + userId);
15082        if ((resultTo != null) && !ordered) {
15083            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
15084        }
15085
15086        userId = handleIncomingUser(callingPid, callingUid, userId,
15087                true, ALLOW_NON_FULL, "broadcast", callerPackage);
15088
15089        // Make sure that the user who is receiving this broadcast is started.
15090        // If not, we will just skip it.
15091
15092
15093        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
15094            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
15095                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
15096                Slog.w(TAG, "Skipping broadcast of " + intent
15097                        + ": user " + userId + " is stopped");
15098                return ActivityManager.BROADCAST_SUCCESS;
15099            }
15100        }
15101
15102        /*
15103         * Prevent non-system code (defined here to be non-persistent
15104         * processes) from sending protected broadcasts.
15105         */
15106        int callingAppId = UserHandle.getAppId(callingUid);
15107        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
15108            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID
15109            || callingAppId == Process.NFC_UID || callingUid == 0) {
15110            // Always okay.
15111        } else if (callerApp == null || !callerApp.persistent) {
15112            try {
15113                if (AppGlobals.getPackageManager().isProtectedBroadcast(
15114                        intent.getAction())) {
15115                    String msg = "Permission Denial: not allowed to send broadcast "
15116                            + intent.getAction() + " from pid="
15117                            + callingPid + ", uid=" + callingUid;
15118                    Slog.w(TAG, msg);
15119                    throw new SecurityException(msg);
15120                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
15121                    // Special case for compatibility: we don't want apps to send this,
15122                    // but historically it has not been protected and apps may be using it
15123                    // to poke their own app widget.  So, instead of making it protected,
15124                    // just limit it to the caller.
15125                    if (callerApp == null) {
15126                        String msg = "Permission Denial: not allowed to send broadcast "
15127                                + intent.getAction() + " from unknown caller.";
15128                        Slog.w(TAG, msg);
15129                        throw new SecurityException(msg);
15130                    } else if (intent.getComponent() != null) {
15131                        // They are good enough to send to an explicit component...  verify
15132                        // it is being sent to the calling app.
15133                        if (!intent.getComponent().getPackageName().equals(
15134                                callerApp.info.packageName)) {
15135                            String msg = "Permission Denial: not allowed to send broadcast "
15136                                    + intent.getAction() + " to "
15137                                    + intent.getComponent().getPackageName() + " from "
15138                                    + callerApp.info.packageName;
15139                            Slog.w(TAG, msg);
15140                            throw new SecurityException(msg);
15141                        }
15142                    } else {
15143                        // Limit broadcast to their own package.
15144                        intent.setPackage(callerApp.info.packageName);
15145                    }
15146                }
15147            } catch (RemoteException e) {
15148                Slog.w(TAG, "Remote exception", e);
15149                return ActivityManager.BROADCAST_SUCCESS;
15150            }
15151        }
15152
15153        // Handle special intents: if this broadcast is from the package
15154        // manager about a package being removed, we need to remove all of
15155        // its activities from the history stack.
15156        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
15157                intent.getAction());
15158        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
15159                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
15160                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
15161                || Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
15162                || uidRemoved) {
15163            if (checkComponentPermission(
15164                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
15165                    callingPid, callingUid, -1, true)
15166                    == PackageManager.PERMISSION_GRANTED) {
15167                if (uidRemoved) {
15168                    final Bundle intentExtras = intent.getExtras();
15169                    final int uid = intentExtras != null
15170                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
15171                    if (uid >= 0) {
15172                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
15173                        synchronized (bs) {
15174                            bs.removeUidStatsLocked(uid);
15175                        }
15176                        mAppOpsService.uidRemoved(uid);
15177                    }
15178                } else {
15179                    // If resources are unavailable just force stop all
15180                    // those packages and flush the attribute cache as well.
15181                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
15182                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15183                        if (list != null && (list.length > 0)) {
15184                            for (String pkg : list) {
15185                                forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
15186                                        "storage unmount");
15187                            }
15188                            cleanupRecentTasksLocked(UserHandle.USER_ALL);
15189                            sendPackageBroadcastLocked(
15190                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
15191                        }
15192                    } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
15193                            intent.getAction())) {
15194                        cleanupRecentTasksLocked(UserHandle.USER_ALL);
15195                    } else {
15196                        Uri data = intent.getData();
15197                        String ssp;
15198                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15199                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
15200                                    intent.getAction());
15201                            boolean fullUninstall = removed &&
15202                                    !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
15203                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
15204                                forceStopPackageLocked(ssp, UserHandle.getAppId(
15205                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
15206                                        false, fullUninstall, userId,
15207                                        removed ? "pkg removed" : "pkg changed");
15208                            }
15209                            if (removed) {
15210                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
15211                                        new String[] {ssp}, userId);
15212                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
15213                                    mAppOpsService.packageRemoved(
15214                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
15215
15216                                    // Remove all permissions granted from/to this package
15217                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
15218                                }
15219                            }
15220                        }
15221                    }
15222                }
15223            } else {
15224                String msg = "Permission Denial: " + intent.getAction()
15225                        + " broadcast from " + callerPackage + " (pid=" + callingPid
15226                        + ", uid=" + callingUid + ")"
15227                        + " requires "
15228                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
15229                Slog.w(TAG, msg);
15230                throw new SecurityException(msg);
15231            }
15232
15233        // Special case for adding a package: by default turn on compatibility
15234        // mode.
15235        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
15236            Uri data = intent.getData();
15237            String ssp;
15238            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
15239                mCompatModePackages.handlePackageAddedLocked(ssp,
15240                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
15241            }
15242        }
15243
15244        /*
15245         * If this is the time zone changed action, queue up a message that will reset the timezone
15246         * of all currently running processes. This message will get queued up before the broadcast
15247         * happens.
15248         */
15249        if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
15250            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
15251        }
15252
15253        /*
15254         * If the user set the time, let all running processes know.
15255         */
15256        if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
15257            final int is24Hour = intent.getBooleanExtra(
15258                    Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
15259            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
15260            BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
15261            synchronized (stats) {
15262                stats.noteCurrentTimeChangedLocked();
15263            }
15264        }
15265
15266        if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
15267            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
15268        }
15269
15270        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
15271            ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
15272            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
15273        }
15274
15275        // Add to the sticky list if requested.
15276        if (sticky) {
15277            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
15278                    callingPid, callingUid)
15279                    != PackageManager.PERMISSION_GRANTED) {
15280                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
15281                        + callingPid + ", uid=" + callingUid
15282                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15283                Slog.w(TAG, msg);
15284                throw new SecurityException(msg);
15285            }
15286            if (requiredPermission != null) {
15287                Slog.w(TAG, "Can't broadcast sticky intent " + intent
15288                        + " and enforce permission " + requiredPermission);
15289                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
15290            }
15291            if (intent.getComponent() != null) {
15292                throw new SecurityException(
15293                        "Sticky broadcasts can't target a specific component");
15294            }
15295            // We use userId directly here, since the "all" target is maintained
15296            // as a separate set of sticky broadcasts.
15297            if (userId != UserHandle.USER_ALL) {
15298                // But first, if this is not a broadcast to all users, then
15299                // make sure it doesn't conflict with an existing broadcast to
15300                // all users.
15301                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
15302                        UserHandle.USER_ALL);
15303                if (stickies != null) {
15304                    ArrayList<Intent> list = stickies.get(intent.getAction());
15305                    if (list != null) {
15306                        int N = list.size();
15307                        int i;
15308                        for (i=0; i<N; i++) {
15309                            if (intent.filterEquals(list.get(i))) {
15310                                throw new IllegalArgumentException(
15311                                        "Sticky broadcast " + intent + " for user "
15312                                        + userId + " conflicts with existing global broadcast");
15313                            }
15314                        }
15315                    }
15316                }
15317            }
15318            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15319            if (stickies == null) {
15320                stickies = new ArrayMap<String, ArrayList<Intent>>();
15321                mStickyBroadcasts.put(userId, stickies);
15322            }
15323            ArrayList<Intent> list = stickies.get(intent.getAction());
15324            if (list == null) {
15325                list = new ArrayList<Intent>();
15326                stickies.put(intent.getAction(), list);
15327            }
15328            int N = list.size();
15329            int i;
15330            for (i=0; i<N; i++) {
15331                if (intent.filterEquals(list.get(i))) {
15332                    // This sticky already exists, replace it.
15333                    list.set(i, new Intent(intent));
15334                    break;
15335                }
15336            }
15337            if (i >= N) {
15338                list.add(new Intent(intent));
15339            }
15340        }
15341
15342        int[] users;
15343        if (userId == UserHandle.USER_ALL) {
15344            // Caller wants broadcast to go to all started users.
15345            users = mStartedUserArray;
15346        } else {
15347            // Caller wants broadcast to go to one specific user.
15348            users = new int[] {userId};
15349        }
15350
15351        // Figure out who all will receive this broadcast.
15352        List receivers = null;
15353        List<BroadcastFilter> registeredReceivers = null;
15354        // Need to resolve the intent to interested receivers...
15355        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
15356                 == 0) {
15357            receivers = collectReceiverComponents(intent, resolvedType, users);
15358        }
15359        if (intent.getComponent() == null) {
15360            registeredReceivers = mReceiverResolver.queryIntent(intent,
15361                    resolvedType, false, userId);
15362        }
15363
15364        final boolean replacePending =
15365                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
15366
15367        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
15368                + " replacePending=" + replacePending);
15369
15370        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
15371        if (!ordered && NR > 0) {
15372            // If we are not serializing this broadcast, then send the
15373            // registered receivers separately so they don't wait for the
15374            // components to be launched.
15375            final BroadcastQueue queue = broadcastQueueForIntent(intent);
15376            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15377                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
15378                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
15379                    ordered, sticky, false, userId);
15380            if (DEBUG_BROADCAST) Slog.v(
15381                    TAG, "Enqueueing parallel broadcast " + r);
15382            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
15383            if (!replaced) {
15384                queue.enqueueParallelBroadcastLocked(r);
15385                queue.scheduleBroadcastsLocked();
15386            }
15387            registeredReceivers = null;
15388            NR = 0;
15389        }
15390
15391        // Merge into one list.
15392        int ir = 0;
15393        if (receivers != null) {
15394            // A special case for PACKAGE_ADDED: do not allow the package
15395            // being added to see this broadcast.  This prevents them from
15396            // using this as a back door to get run as soon as they are
15397            // installed.  Maybe in the future we want to have a special install
15398            // broadcast or such for apps, but we'd like to deliberately make
15399            // this decision.
15400            String skipPackages[] = null;
15401            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
15402                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
15403                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
15404                Uri data = intent.getData();
15405                if (data != null) {
15406                    String pkgName = data.getSchemeSpecificPart();
15407                    if (pkgName != null) {
15408                        skipPackages = new String[] { pkgName };
15409                    }
15410                }
15411            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
15412                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
15413            }
15414            if (skipPackages != null && (skipPackages.length > 0)) {
15415                for (String skipPackage : skipPackages) {
15416                    if (skipPackage != null) {
15417                        int NT = receivers.size();
15418                        for (int it=0; it<NT; it++) {
15419                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
15420                            if (curt.activityInfo.packageName.equals(skipPackage)) {
15421                                receivers.remove(it);
15422                                it--;
15423                                NT--;
15424                            }
15425                        }
15426                    }
15427                }
15428            }
15429
15430            int NT = receivers != null ? receivers.size() : 0;
15431            int it = 0;
15432            ResolveInfo curt = null;
15433            BroadcastFilter curr = null;
15434            while (it < NT && ir < NR) {
15435                if (curt == null) {
15436                    curt = (ResolveInfo)receivers.get(it);
15437                }
15438                if (curr == null) {
15439                    curr = registeredReceivers.get(ir);
15440                }
15441                if (curr.getPriority() >= curt.priority) {
15442                    // Insert this broadcast record into the final list.
15443                    receivers.add(it, curr);
15444                    ir++;
15445                    curr = null;
15446                    it++;
15447                    NT++;
15448                } else {
15449                    // Skip to the next ResolveInfo in the final list.
15450                    it++;
15451                    curt = null;
15452                }
15453            }
15454        }
15455        while (ir < NR) {
15456            if (receivers == null) {
15457                receivers = new ArrayList();
15458            }
15459            receivers.add(registeredReceivers.get(ir));
15460            ir++;
15461        }
15462
15463        if ((receivers != null && receivers.size() > 0)
15464                || resultTo != null) {
15465            BroadcastQueue queue = broadcastQueueForIntent(intent);
15466            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
15467                    callerPackage, callingPid, callingUid, resolvedType,
15468                    requiredPermission, appOp, receivers, resultTo, resultCode,
15469                    resultData, map, ordered, sticky, false, userId);
15470            if (DEBUG_BROADCAST) Slog.v(
15471                    TAG, "Enqueueing ordered broadcast " + r
15472                    + ": prev had " + queue.mOrderedBroadcasts.size());
15473            if (DEBUG_BROADCAST) {
15474                int seq = r.intent.getIntExtra("seq", -1);
15475                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
15476            }
15477            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
15478            if (!replaced) {
15479                queue.enqueueOrderedBroadcastLocked(r);
15480                queue.scheduleBroadcastsLocked();
15481            }
15482        }
15483
15484        return ActivityManager.BROADCAST_SUCCESS;
15485    }
15486
15487    final Intent verifyBroadcastLocked(Intent intent) {
15488        // Refuse possible leaked file descriptors
15489        if (intent != null && intent.hasFileDescriptors() == true) {
15490            throw new IllegalArgumentException("File descriptors passed in Intent");
15491        }
15492
15493        int flags = intent.getFlags();
15494
15495        if (!mProcessesReady) {
15496            // if the caller really truly claims to know what they're doing, go
15497            // ahead and allow the broadcast without launching any receivers
15498            if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
15499                intent = new Intent(intent);
15500                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
15501            } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
15502                Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
15503                        + " before boot completion");
15504                throw new IllegalStateException("Cannot broadcast before boot completed");
15505            }
15506        }
15507
15508        if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
15509            throw new IllegalArgumentException(
15510                    "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
15511        }
15512
15513        return intent;
15514    }
15515
15516    public final int broadcastIntent(IApplicationThread caller,
15517            Intent intent, String resolvedType, IIntentReceiver resultTo,
15518            int resultCode, String resultData, Bundle map,
15519            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
15520        enforceNotIsolatedCaller("broadcastIntent");
15521        synchronized(this) {
15522            intent = verifyBroadcastLocked(intent);
15523
15524            final ProcessRecord callerApp = getRecordForAppLocked(caller);
15525            final int callingPid = Binder.getCallingPid();
15526            final int callingUid = Binder.getCallingUid();
15527            final long origId = Binder.clearCallingIdentity();
15528            int res = broadcastIntentLocked(callerApp,
15529                    callerApp != null ? callerApp.info.packageName : null,
15530                    intent, resolvedType, resultTo,
15531                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
15532                    callingPid, callingUid, userId);
15533            Binder.restoreCallingIdentity(origId);
15534            return res;
15535        }
15536    }
15537
15538    int broadcastIntentInPackage(String packageName, int uid,
15539            Intent intent, String resolvedType, IIntentReceiver resultTo,
15540            int resultCode, String resultData, Bundle map,
15541            String requiredPermission, boolean serialized, boolean sticky, int userId) {
15542        synchronized(this) {
15543            intent = verifyBroadcastLocked(intent);
15544
15545            final long origId = Binder.clearCallingIdentity();
15546            int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
15547                    resultTo, resultCode, resultData, map, requiredPermission,
15548                    AppOpsManager.OP_NONE, serialized, sticky, -1, uid, userId);
15549            Binder.restoreCallingIdentity(origId);
15550            return res;
15551        }
15552    }
15553
15554    public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
15555        // Refuse possible leaked file descriptors
15556        if (intent != null && intent.hasFileDescriptors() == true) {
15557            throw new IllegalArgumentException("File descriptors passed in Intent");
15558        }
15559
15560        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15561                userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
15562
15563        synchronized(this) {
15564            if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
15565                    != PackageManager.PERMISSION_GRANTED) {
15566                String msg = "Permission Denial: unbroadcastIntent() from pid="
15567                        + Binder.getCallingPid()
15568                        + ", uid=" + Binder.getCallingUid()
15569                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
15570                Slog.w(TAG, msg);
15571                throw new SecurityException(msg);
15572            }
15573            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
15574            if (stickies != null) {
15575                ArrayList<Intent> list = stickies.get(intent.getAction());
15576                if (list != null) {
15577                    int N = list.size();
15578                    int i;
15579                    for (i=0; i<N; i++) {
15580                        if (intent.filterEquals(list.get(i))) {
15581                            list.remove(i);
15582                            break;
15583                        }
15584                    }
15585                    if (list.size() <= 0) {
15586                        stickies.remove(intent.getAction());
15587                    }
15588                }
15589                if (stickies.size() <= 0) {
15590                    mStickyBroadcasts.remove(userId);
15591                }
15592            }
15593        }
15594    }
15595
15596    private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
15597            String resultData, Bundle resultExtras, boolean resultAbort) {
15598        final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
15599        if (r == null) {
15600            Slog.w(TAG, "finishReceiver called but not found on queue");
15601            return false;
15602        }
15603
15604        return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort, false);
15605    }
15606
15607    void backgroundServicesFinishedLocked(int userId) {
15608        for (BroadcastQueue queue : mBroadcastQueues) {
15609            queue.backgroundServicesFinishedLocked(userId);
15610        }
15611    }
15612
15613    public void finishReceiver(IBinder who, int resultCode, String resultData,
15614            Bundle resultExtras, boolean resultAbort) {
15615        if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
15616
15617        // Refuse possible leaked file descriptors
15618        if (resultExtras != null && resultExtras.hasFileDescriptors()) {
15619            throw new IllegalArgumentException("File descriptors passed in Bundle");
15620        }
15621
15622        final long origId = Binder.clearCallingIdentity();
15623        try {
15624            boolean doNext = false;
15625            BroadcastRecord r;
15626
15627            synchronized(this) {
15628                r = broadcastRecordForReceiverLocked(who);
15629                if (r != null) {
15630                    doNext = r.queue.finishReceiverLocked(r, resultCode,
15631                        resultData, resultExtras, resultAbort, true);
15632                }
15633            }
15634
15635            if (doNext) {
15636                r.queue.processNextBroadcast(false);
15637            }
15638            trimApplications();
15639        } finally {
15640            Binder.restoreCallingIdentity(origId);
15641        }
15642    }
15643
15644    // =========================================================
15645    // INSTRUMENTATION
15646    // =========================================================
15647
15648    public boolean startInstrumentation(ComponentName className,
15649            String profileFile, int flags, Bundle arguments,
15650            IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
15651            int userId, String abiOverride) {
15652        enforceNotIsolatedCaller("startInstrumentation");
15653        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
15654                userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
15655        // Refuse possible leaked file descriptors
15656        if (arguments != null && arguments.hasFileDescriptors()) {
15657            throw new IllegalArgumentException("File descriptors passed in Bundle");
15658        }
15659
15660        synchronized(this) {
15661            InstrumentationInfo ii = null;
15662            ApplicationInfo ai = null;
15663            try {
15664                ii = mContext.getPackageManager().getInstrumentationInfo(
15665                    className, STOCK_PM_FLAGS);
15666                ai = AppGlobals.getPackageManager().getApplicationInfo(
15667                        ii.targetPackage, STOCK_PM_FLAGS, userId);
15668            } catch (PackageManager.NameNotFoundException e) {
15669            } catch (RemoteException e) {
15670            }
15671            if (ii == null) {
15672                reportStartInstrumentationFailure(watcher, className,
15673                        "Unable to find instrumentation info for: " + className);
15674                return false;
15675            }
15676            if (ai == null) {
15677                reportStartInstrumentationFailure(watcher, className,
15678                        "Unable to find instrumentation target package: " + ii.targetPackage);
15679                return false;
15680            }
15681
15682            int match = mContext.getPackageManager().checkSignatures(
15683                    ii.targetPackage, ii.packageName);
15684            if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
15685                String msg = "Permission Denial: starting instrumentation "
15686                        + className + " from pid="
15687                        + Binder.getCallingPid()
15688                        + ", uid=" + Binder.getCallingPid()
15689                        + " not allowed because package " + ii.packageName
15690                        + " does not have a signature matching the target "
15691                        + ii.targetPackage;
15692                reportStartInstrumentationFailure(watcher, className, msg);
15693                throw new SecurityException(msg);
15694            }
15695
15696            final long origId = Binder.clearCallingIdentity();
15697            // Instrumentation can kill and relaunch even persistent processes
15698            forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
15699                    "start instr");
15700            ProcessRecord app = addAppLocked(ai, false, abiOverride);
15701            app.instrumentationClass = className;
15702            app.instrumentationInfo = ai;
15703            app.instrumentationProfileFile = profileFile;
15704            app.instrumentationArguments = arguments;
15705            app.instrumentationWatcher = watcher;
15706            app.instrumentationUiAutomationConnection = uiAutomationConnection;
15707            app.instrumentationResultClass = className;
15708            Binder.restoreCallingIdentity(origId);
15709        }
15710
15711        return true;
15712    }
15713
15714    /**
15715     * Report errors that occur while attempting to start Instrumentation.  Always writes the
15716     * error to the logs, but if somebody is watching, send the report there too.  This enables
15717     * the "am" command to report errors with more information.
15718     *
15719     * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
15720     * @param cn The component name of the instrumentation.
15721     * @param report The error report.
15722     */
15723    private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
15724            ComponentName cn, String report) {
15725        Slog.w(TAG, report);
15726        try {
15727            if (watcher != null) {
15728                Bundle results = new Bundle();
15729                results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
15730                results.putString("Error", report);
15731                watcher.instrumentationStatus(cn, -1, results);
15732            }
15733        } catch (RemoteException e) {
15734            Slog.w(TAG, e);
15735        }
15736    }
15737
15738    void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
15739        if (app.instrumentationWatcher != null) {
15740            try {
15741                // NOTE:  IInstrumentationWatcher *must* be oneway here
15742                app.instrumentationWatcher.instrumentationFinished(
15743                    app.instrumentationClass,
15744                    resultCode,
15745                    results);
15746            } catch (RemoteException e) {
15747            }
15748        }
15749        if (app.instrumentationUiAutomationConnection != null) {
15750            try {
15751                app.instrumentationUiAutomationConnection.shutdown();
15752            } catch (RemoteException re) {
15753                /* ignore */
15754            }
15755            // Only a UiAutomation can set this flag and now that
15756            // it is finished we make sure it is reset to its default.
15757            mUserIsMonkey = false;
15758        }
15759        app.instrumentationWatcher = null;
15760        app.instrumentationUiAutomationConnection = null;
15761        app.instrumentationClass = null;
15762        app.instrumentationInfo = null;
15763        app.instrumentationProfileFile = null;
15764        app.instrumentationArguments = null;
15765
15766        forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
15767                "finished inst");
15768    }
15769
15770    public void finishInstrumentation(IApplicationThread target,
15771            int resultCode, Bundle results) {
15772        int userId = UserHandle.getCallingUserId();
15773        // Refuse possible leaked file descriptors
15774        if (results != null && results.hasFileDescriptors()) {
15775            throw new IllegalArgumentException("File descriptors passed in Intent");
15776        }
15777
15778        synchronized(this) {
15779            ProcessRecord app = getRecordForAppLocked(target);
15780            if (app == null) {
15781                Slog.w(TAG, "finishInstrumentation: no app for " + target);
15782                return;
15783            }
15784            final long origId = Binder.clearCallingIdentity();
15785            finishInstrumentationLocked(app, resultCode, results);
15786            Binder.restoreCallingIdentity(origId);
15787        }
15788    }
15789
15790    // =========================================================
15791    // CONFIGURATION
15792    // =========================================================
15793
15794    public ConfigurationInfo getDeviceConfigurationInfo() {
15795        ConfigurationInfo config = new ConfigurationInfo();
15796        synchronized (this) {
15797            config.reqTouchScreen = mConfiguration.touchscreen;
15798            config.reqKeyboardType = mConfiguration.keyboard;
15799            config.reqNavigation = mConfiguration.navigation;
15800            if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
15801                    || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
15802                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
15803            }
15804            if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
15805                    && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
15806                config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
15807            }
15808            config.reqGlEsVersion = GL_ES_VERSION;
15809        }
15810        return config;
15811    }
15812
15813    ActivityStack getFocusedStack() {
15814        return mStackSupervisor.getFocusedStack();
15815    }
15816
15817    public Configuration getConfiguration() {
15818        Configuration ci;
15819        synchronized(this) {
15820            ci = new Configuration(mConfiguration);
15821        }
15822        return ci;
15823    }
15824
15825    public void updatePersistentConfiguration(Configuration values) {
15826        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15827                "updateConfiguration()");
15828        enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
15829                "updateConfiguration()");
15830        if (values == null) {
15831            throw new NullPointerException("Configuration must not be null");
15832        }
15833
15834        synchronized(this) {
15835            final long origId = Binder.clearCallingIdentity();
15836            updateConfigurationLocked(values, null, true, false);
15837            Binder.restoreCallingIdentity(origId);
15838        }
15839    }
15840
15841    public void updateConfiguration(Configuration values) {
15842        enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
15843                "updateConfiguration()");
15844
15845        synchronized(this) {
15846            if (values == null && mWindowManager != null) {
15847                // sentinel: fetch the current configuration from the window manager
15848                values = mWindowManager.computeNewConfiguration();
15849            }
15850
15851            if (mWindowManager != null) {
15852                mProcessList.applyDisplaySize(mWindowManager);
15853            }
15854
15855            final long origId = Binder.clearCallingIdentity();
15856            if (values != null) {
15857                Settings.System.clearConfiguration(values);
15858            }
15859            updateConfigurationLocked(values, null, false, false);
15860            Binder.restoreCallingIdentity(origId);
15861        }
15862    }
15863
15864    /**
15865     * Do either or both things: (1) change the current configuration, and (2)
15866     * make sure the given activity is running with the (now) current
15867     * configuration.  Returns true if the activity has been left running, or
15868     * false if <var>starting</var> is being destroyed to match the new
15869     * configuration.
15870     * @param persistent TODO
15871     */
15872    boolean updateConfigurationLocked(Configuration values,
15873            ActivityRecord starting, boolean persistent, boolean initLocale) {
15874        int changes = 0;
15875
15876        if (values != null) {
15877            Configuration newConfig = new Configuration(mConfiguration);
15878            changes = newConfig.updateFrom(values);
15879            if (changes != 0) {
15880                if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
15881                    Slog.i(TAG, "Updating configuration to: " + values);
15882                }
15883
15884                EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
15885
15886                if (values.locale != null && !initLocale) {
15887                    saveLocaleLocked(values.locale,
15888                                     !values.locale.equals(mConfiguration.locale),
15889                                     values.userSetLocale);
15890                }
15891
15892                mConfigurationSeq++;
15893                if (mConfigurationSeq <= 0) {
15894                    mConfigurationSeq = 1;
15895                }
15896                newConfig.seq = mConfigurationSeq;
15897                mConfiguration = newConfig;
15898                Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
15899                //mUsageStatsService.noteStartConfig(newConfig);
15900
15901                final Configuration configCopy = new Configuration(mConfiguration);
15902
15903                // TODO: If our config changes, should we auto dismiss any currently
15904                // showing dialogs?
15905                mShowDialogs = shouldShowDialogs(newConfig);
15906
15907                AttributeCache ac = AttributeCache.instance();
15908                if (ac != null) {
15909                    ac.updateConfiguration(configCopy);
15910                }
15911
15912                // Make sure all resources in our process are updated
15913                // right now, so that anyone who is going to retrieve
15914                // resource values after we return will be sure to get
15915                // the new ones.  This is especially important during
15916                // boot, where the first config change needs to guarantee
15917                // all resources have that config before following boot
15918                // code is executed.
15919                mSystemThread.applyConfigurationToResources(configCopy);
15920
15921                if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
15922                    Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
15923                    msg.obj = new Configuration(configCopy);
15924                    mHandler.sendMessage(msg);
15925                }
15926
15927                for (int i=mLruProcesses.size()-1; i>=0; i--) {
15928                    ProcessRecord app = mLruProcesses.get(i);
15929                    try {
15930                        if (app.thread != null) {
15931                            if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
15932                                    + app.processName + " new config " + mConfiguration);
15933                            app.thread.scheduleConfigurationChanged(configCopy);
15934                        }
15935                    } catch (Exception e) {
15936                    }
15937                }
15938                Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
15939                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
15940                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
15941                        | Intent.FLAG_RECEIVER_FOREGROUND);
15942                broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
15943                        null, AppOpsManager.OP_NONE, false, false, MY_PID,
15944                        Process.SYSTEM_UID, UserHandle.USER_ALL);
15945                if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
15946                    intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
15947                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
15948                    broadcastIntentLocked(null, null, intent,
15949                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
15950                            false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
15951                }
15952            }
15953        }
15954
15955        boolean kept = true;
15956        final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
15957        // mainStack is null during startup.
15958        if (mainStack != null) {
15959            if (changes != 0 && starting == null) {
15960                // If the configuration changed, and the caller is not already
15961                // in the process of starting an activity, then find the top
15962                // activity to check if its configuration needs to change.
15963                starting = mainStack.topRunningActivityLocked(null);
15964            }
15965
15966            if (starting != null) {
15967                kept = mainStack.ensureActivityConfigurationLocked(starting, changes);
15968                // And we need to make sure at this point that all other activities
15969                // are made visible with the correct configuration.
15970                mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes);
15971            }
15972        }
15973
15974        if (values != null && mWindowManager != null) {
15975            mWindowManager.setNewConfiguration(mConfiguration);
15976        }
15977
15978        return kept;
15979    }
15980
15981    /**
15982     * Decide based on the configuration whether we should shouw the ANR,
15983     * crash, etc dialogs.  The idea is that if there is no affordnace to
15984     * press the on-screen buttons, we shouldn't show the dialog.
15985     *
15986     * A thought: SystemUI might also want to get told about this, the Power
15987     * dialog / global actions also might want different behaviors.
15988     */
15989    private static final boolean shouldShowDialogs(Configuration config) {
15990        return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
15991                && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
15992    }
15993
15994    /**
15995     * Save the locale.  You must be inside a synchronized (this) block.
15996     */
15997    private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
15998        if(isDiff) {
15999            SystemProperties.set("user.language", l.getLanguage());
16000            SystemProperties.set("user.region", l.getCountry());
16001        }
16002
16003        if(isPersist) {
16004            SystemProperties.set("persist.sys.language", l.getLanguage());
16005            SystemProperties.set("persist.sys.country", l.getCountry());
16006            SystemProperties.set("persist.sys.localevar", l.getVariant());
16007        }
16008    }
16009
16010    @Override
16011    public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
16012        synchronized (this) {
16013            ActivityRecord srec = ActivityRecord.forToken(token);
16014            if (srec.task != null && srec.task.stack != null) {
16015                return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
16016            }
16017        }
16018        return false;
16019    }
16020
16021    public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
16022            Intent resultData) {
16023
16024        synchronized (this) {
16025            final ActivityStack stack = ActivityRecord.getStackLocked(token);
16026            if (stack != null) {
16027                return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
16028            }
16029            return false;
16030        }
16031    }
16032
16033    public int getLaunchedFromUid(IBinder activityToken) {
16034        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16035        if (srec == null) {
16036            return -1;
16037        }
16038        return srec.launchedFromUid;
16039    }
16040
16041    public String getLaunchedFromPackage(IBinder activityToken) {
16042        ActivityRecord srec = ActivityRecord.forToken(activityToken);
16043        if (srec == null) {
16044            return null;
16045        }
16046        return srec.launchedFromPackage;
16047    }
16048
16049    // =========================================================
16050    // LIFETIME MANAGEMENT
16051    // =========================================================
16052
16053    // Returns which broadcast queue the app is the current [or imminent] receiver
16054    // on, or 'null' if the app is not an active broadcast recipient.
16055    private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
16056        BroadcastRecord r = app.curReceiver;
16057        if (r != null) {
16058            return r.queue;
16059        }
16060
16061        // It's not the current receiver, but it might be starting up to become one
16062        synchronized (this) {
16063            for (BroadcastQueue queue : mBroadcastQueues) {
16064                r = queue.mPendingBroadcast;
16065                if (r != null && r.curApp == app) {
16066                    // found it; report which queue it's in
16067                    return queue;
16068                }
16069            }
16070        }
16071
16072        return null;
16073    }
16074
16075    private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
16076            boolean doingAll, long now) {
16077        if (mAdjSeq == app.adjSeq) {
16078            // This adjustment has already been computed.
16079            return app.curRawAdj;
16080        }
16081
16082        if (app.thread == null) {
16083            app.adjSeq = mAdjSeq;
16084            app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16085            app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16086            return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
16087        }
16088
16089        app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
16090        app.adjSource = null;
16091        app.adjTarget = null;
16092        app.empty = false;
16093        app.cached = false;
16094
16095        final int activitiesSize = app.activities.size();
16096
16097        if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16098            // The max adjustment doesn't allow this app to be anything
16099            // below foreground, so it is not worth doing work for it.
16100            app.adjType = "fixed";
16101            app.adjSeq = mAdjSeq;
16102            app.curRawAdj = app.maxAdj;
16103            app.foregroundActivities = false;
16104            app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
16105            app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
16106            // System processes can do UI, and when they do we want to have
16107            // them trim their memory after the user leaves the UI.  To
16108            // facilitate this, here we need to determine whether or not it
16109            // is currently showing UI.
16110            app.systemNoUi = true;
16111            if (app == TOP_APP) {
16112                app.systemNoUi = false;
16113            } else if (activitiesSize > 0) {
16114                for (int j = 0; j < activitiesSize; j++) {
16115                    final ActivityRecord r = app.activities.get(j);
16116                    if (r.visible) {
16117                        app.systemNoUi = false;
16118                    }
16119                }
16120            }
16121            if (!app.systemNoUi) {
16122                app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
16123            }
16124            return (app.curAdj=app.maxAdj);
16125        }
16126
16127        app.systemNoUi = false;
16128
16129        // Determine the importance of the process, starting with most
16130        // important to least, and assign an appropriate OOM adjustment.
16131        int adj;
16132        int schedGroup;
16133        int procState;
16134        boolean foregroundActivities = false;
16135        BroadcastQueue queue;
16136        if (app == TOP_APP) {
16137            // The last app on the list is the foreground app.
16138            adj = ProcessList.FOREGROUND_APP_ADJ;
16139            schedGroup = Process.THREAD_GROUP_DEFAULT;
16140            app.adjType = "top-activity";
16141            foregroundActivities = true;
16142            procState = ActivityManager.PROCESS_STATE_TOP;
16143        } else if (app.instrumentationClass != null) {
16144            // Don't want to kill running instrumentation.
16145            adj = ProcessList.FOREGROUND_APP_ADJ;
16146            schedGroup = Process.THREAD_GROUP_DEFAULT;
16147            app.adjType = "instrumentation";
16148            procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16149        } else if ((queue = isReceivingBroadcast(app)) != null) {
16150            // An app that is currently receiving a broadcast also
16151            // counts as being in the foreground for OOM killer purposes.
16152            // It's placed in a sched group based on the nature of the
16153            // broadcast as reflected by which queue it's active in.
16154            adj = ProcessList.FOREGROUND_APP_ADJ;
16155            schedGroup = (queue == mFgBroadcastQueue)
16156                    ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16157            app.adjType = "broadcast";
16158            procState = ActivityManager.PROCESS_STATE_RECEIVER;
16159        } else if (app.executingServices.size() > 0) {
16160            // An app that is currently executing a service callback also
16161            // counts as being in the foreground.
16162            adj = ProcessList.FOREGROUND_APP_ADJ;
16163            schedGroup = app.execServicesFg ?
16164                    Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
16165            app.adjType = "exec-service";
16166            procState = ActivityManager.PROCESS_STATE_SERVICE;
16167            //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
16168        } else {
16169            // As far as we know the process is empty.  We may change our mind later.
16170            schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16171            // At this point we don't actually know the adjustment.  Use the cached adj
16172            // value that the caller wants us to.
16173            adj = cachedAdj;
16174            procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16175            app.cached = true;
16176            app.empty = true;
16177            app.adjType = "cch-empty";
16178        }
16179
16180        // Examine all activities if not already foreground.
16181        if (!foregroundActivities && activitiesSize > 0) {
16182            for (int j = 0; j < activitiesSize; j++) {
16183                final ActivityRecord r = app.activities.get(j);
16184                if (r.app != app) {
16185                    Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
16186                            + app + "?!?");
16187                    continue;
16188                }
16189                if (r.visible) {
16190                    // App has a visible activity; only upgrade adjustment.
16191                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16192                        adj = ProcessList.VISIBLE_APP_ADJ;
16193                        app.adjType = "visible";
16194                    }
16195                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16196                        procState = ActivityManager.PROCESS_STATE_TOP;
16197                    }
16198                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16199                    app.cached = false;
16200                    app.empty = false;
16201                    foregroundActivities = true;
16202                    break;
16203                } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
16204                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16205                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16206                        app.adjType = "pausing";
16207                    }
16208                    if (procState > ActivityManager.PROCESS_STATE_TOP) {
16209                        procState = ActivityManager.PROCESS_STATE_TOP;
16210                    }
16211                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16212                    app.cached = false;
16213                    app.empty = false;
16214                    foregroundActivities = true;
16215                } else if (r.state == ActivityState.STOPPING) {
16216                    if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16217                        adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16218                        app.adjType = "stopping";
16219                    }
16220                    // For the process state, we will at this point consider the
16221                    // process to be cached.  It will be cached either as an activity
16222                    // or empty depending on whether the activity is finishing.  We do
16223                    // this so that we can treat the process as cached for purposes of
16224                    // memory trimming (determing current memory level, trim command to
16225                    // send to process) since there can be an arbitrary number of stopping
16226                    // processes and they should soon all go into the cached state.
16227                    if (!r.finishing) {
16228                        if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16229                            procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16230                        }
16231                    }
16232                    app.cached = false;
16233                    app.empty = false;
16234                    foregroundActivities = true;
16235                } else {
16236                    if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16237                        procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16238                        app.adjType = "cch-act";
16239                    }
16240                }
16241            }
16242        }
16243
16244        if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16245            if (app.foregroundServices) {
16246                // The user is aware of this app, so make it visible.
16247                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16248                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16249                app.cached = false;
16250                app.adjType = "fg-service";
16251                schedGroup = Process.THREAD_GROUP_DEFAULT;
16252            } else if (app.forcingToForeground != null) {
16253                // The user is aware of this app, so make it visible.
16254                adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16255                procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16256                app.cached = false;
16257                app.adjType = "force-fg";
16258                app.adjSource = app.forcingToForeground;
16259                schedGroup = Process.THREAD_GROUP_DEFAULT;
16260            }
16261        }
16262
16263        if (app == mHeavyWeightProcess) {
16264            if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
16265                // We don't want to kill the current heavy-weight process.
16266                adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
16267                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16268                app.cached = false;
16269                app.adjType = "heavy";
16270            }
16271            if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
16272                procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
16273            }
16274        }
16275
16276        if (app == mHomeProcess) {
16277            if (adj > ProcessList.HOME_APP_ADJ) {
16278                // This process is hosting what we currently consider to be the
16279                // home app, so we don't want to let it go into the background.
16280                adj = ProcessList.HOME_APP_ADJ;
16281                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16282                app.cached = false;
16283                app.adjType = "home";
16284            }
16285            if (procState > ActivityManager.PROCESS_STATE_HOME) {
16286                procState = ActivityManager.PROCESS_STATE_HOME;
16287            }
16288        }
16289
16290        if (app == mPreviousProcess && app.activities.size() > 0) {
16291            if (adj > ProcessList.PREVIOUS_APP_ADJ) {
16292                // This was the previous process that showed UI to the user.
16293                // We want to try to keep it around more aggressively, to give
16294                // a good experience around switching between two apps.
16295                adj = ProcessList.PREVIOUS_APP_ADJ;
16296                schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
16297                app.cached = false;
16298                app.adjType = "previous";
16299            }
16300            if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
16301                procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
16302            }
16303        }
16304
16305        if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
16306                + " reason=" + app.adjType);
16307
16308        // By default, we use the computed adjustment.  It may be changed if
16309        // there are applications dependent on our services or providers, but
16310        // this gives us a baseline and makes sure we don't get into an
16311        // infinite recursion.
16312        app.adjSeq = mAdjSeq;
16313        app.curRawAdj = adj;
16314        app.hasStartedServices = false;
16315
16316        if (mBackupTarget != null && app == mBackupTarget.app) {
16317            // If possible we want to avoid killing apps while they're being backed up
16318            if (adj > ProcessList.BACKUP_APP_ADJ) {
16319                if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
16320                adj = ProcessList.BACKUP_APP_ADJ;
16321                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16322                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16323                }
16324                app.adjType = "backup";
16325                app.cached = false;
16326            }
16327            if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
16328                procState = ActivityManager.PROCESS_STATE_BACKUP;
16329            }
16330        }
16331
16332        boolean mayBeTop = false;
16333
16334        for (int is = app.services.size()-1;
16335                is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16336                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16337                        || procState > ActivityManager.PROCESS_STATE_TOP);
16338                is--) {
16339            ServiceRecord s = app.services.valueAt(is);
16340            if (s.startRequested) {
16341                app.hasStartedServices = true;
16342                if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
16343                    procState = ActivityManager.PROCESS_STATE_SERVICE;
16344                }
16345                if (app.hasShownUi && app != mHomeProcess) {
16346                    // If this process has shown some UI, let it immediately
16347                    // go to the LRU list because it may be pretty heavy with
16348                    // UI stuff.  We'll tag it with a label just to help
16349                    // debug and understand what is going on.
16350                    if (adj > ProcessList.SERVICE_ADJ) {
16351                        app.adjType = "cch-started-ui-services";
16352                    }
16353                } else {
16354                    if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16355                        // This service has seen some activity within
16356                        // recent memory, so we will keep its process ahead
16357                        // of the background processes.
16358                        if (adj > ProcessList.SERVICE_ADJ) {
16359                            adj = ProcessList.SERVICE_ADJ;
16360                            app.adjType = "started-services";
16361                            app.cached = false;
16362                        }
16363                    }
16364                    // If we have let the service slide into the background
16365                    // state, still have some text describing what it is doing
16366                    // even though the service no longer has an impact.
16367                    if (adj > ProcessList.SERVICE_ADJ) {
16368                        app.adjType = "cch-started-services";
16369                    }
16370                }
16371            }
16372            for (int conni = s.connections.size()-1;
16373                    conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16374                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16375                            || procState > ActivityManager.PROCESS_STATE_TOP);
16376                    conni--) {
16377                ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
16378                for (int i = 0;
16379                        i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
16380                                || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16381                                || procState > ActivityManager.PROCESS_STATE_TOP);
16382                        i++) {
16383                    // XXX should compute this based on the max of
16384                    // all connected clients.
16385                    ConnectionRecord cr = clist.get(i);
16386                    if (cr.binding.client == app) {
16387                        // Binding to ourself is not interesting.
16388                        continue;
16389                    }
16390                    if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
16391                        ProcessRecord client = cr.binding.client;
16392                        int clientAdj = computeOomAdjLocked(client, cachedAdj,
16393                                TOP_APP, doingAll, now);
16394                        int clientProcState = client.curProcState;
16395                        if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16396                            // If the other app is cached for any reason, for purposes here
16397                            // we are going to consider it empty.  The specific cached state
16398                            // doesn't propagate except under certain conditions.
16399                            clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16400                        }
16401                        String adjType = null;
16402                        if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
16403                            // Not doing bind OOM management, so treat
16404                            // this guy more like a started service.
16405                            if (app.hasShownUi && app != mHomeProcess) {
16406                                // If this process has shown some UI, let it immediately
16407                                // go to the LRU list because it may be pretty heavy with
16408                                // UI stuff.  We'll tag it with a label just to help
16409                                // debug and understand what is going on.
16410                                if (adj > clientAdj) {
16411                                    adjType = "cch-bound-ui-services";
16412                                }
16413                                app.cached = false;
16414                                clientAdj = adj;
16415                                clientProcState = procState;
16416                            } else {
16417                                if (now >= (s.lastActivity
16418                                        + ActiveServices.MAX_SERVICE_INACTIVITY)) {
16419                                    // This service has not seen activity within
16420                                    // recent memory, so allow it to drop to the
16421                                    // LRU list if there is no other reason to keep
16422                                    // it around.  We'll also tag it with a label just
16423                                    // to help debug and undertand what is going on.
16424                                    if (adj > clientAdj) {
16425                                        adjType = "cch-bound-services";
16426                                    }
16427                                    clientAdj = adj;
16428                                }
16429                            }
16430                        }
16431                        if (adj > clientAdj) {
16432                            // If this process has recently shown UI, and
16433                            // the process that is binding to it is less
16434                            // important than being visible, then we don't
16435                            // care about the binding as much as we care
16436                            // about letting this process get into the LRU
16437                            // list to be killed and restarted if needed for
16438                            // memory.
16439                            if (app.hasShownUi && app != mHomeProcess
16440                                    && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16441                                adjType = "cch-bound-ui-services";
16442                            } else {
16443                                if ((cr.flags&(Context.BIND_ABOVE_CLIENT
16444                                        |Context.BIND_IMPORTANT)) != 0) {
16445                                    adj = clientAdj;
16446                                } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
16447                                        && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
16448                                        && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16449                                    adj = ProcessList.PERCEPTIBLE_APP_ADJ;
16450                                } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
16451                                    adj = clientAdj;
16452                                } else {
16453                                    if (adj > ProcessList.VISIBLE_APP_ADJ) {
16454                                        adj = ProcessList.VISIBLE_APP_ADJ;
16455                                    }
16456                                }
16457                                if (!client.cached) {
16458                                    app.cached = false;
16459                                }
16460                                adjType = "service";
16461                            }
16462                        }
16463                        if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16464                            if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16465                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16466                            }
16467                            if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16468                                if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16469                                    // Special handling of clients who are in the top state.
16470                                    // We *may* want to consider this process to be in the
16471                                    // top state as well, but only if there is not another
16472                                    // reason for it to be running.  Being on the top is a
16473                                    // special state, meaning you are specifically running
16474                                    // for the current top app.  If the process is already
16475                                    // running in the background for some other reason, it
16476                                    // is more important to continue considering it to be
16477                                    // in the background state.
16478                                    mayBeTop = true;
16479                                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16480                                } else {
16481                                    // Special handling for above-top states (persistent
16482                                    // processes).  These should not bring the current process
16483                                    // into the top state, since they are not on top.  Instead
16484                                    // give them the best state after that.
16485                                    clientProcState =
16486                                            ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16487                                }
16488                            }
16489                        } else {
16490                            if (clientProcState <
16491                                    ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
16492                                clientProcState =
16493                                        ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
16494                            }
16495                        }
16496                        if (procState > clientProcState) {
16497                            procState = clientProcState;
16498                        }
16499                        if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
16500                                && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
16501                            app.pendingUiClean = true;
16502                        }
16503                        if (adjType != null) {
16504                            app.adjType = adjType;
16505                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16506                                    .REASON_SERVICE_IN_USE;
16507                            app.adjSource = cr.binding.client;
16508                            app.adjSourceProcState = clientProcState;
16509                            app.adjTarget = s.name;
16510                        }
16511                    }
16512                    if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
16513                        app.treatLikeActivity = true;
16514                    }
16515                    final ActivityRecord a = cr.activity;
16516                    if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
16517                        if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
16518                                (a.visible || a.state == ActivityState.RESUMED
16519                                 || a.state == ActivityState.PAUSING)) {
16520                            adj = ProcessList.FOREGROUND_APP_ADJ;
16521                            if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
16522                                schedGroup = Process.THREAD_GROUP_DEFAULT;
16523                            }
16524                            app.cached = false;
16525                            app.adjType = "service";
16526                            app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16527                                    .REASON_SERVICE_IN_USE;
16528                            app.adjSource = a;
16529                            app.adjSourceProcState = procState;
16530                            app.adjTarget = s.name;
16531                        }
16532                    }
16533                }
16534            }
16535        }
16536
16537        for (int provi = app.pubProviders.size()-1;
16538                provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16539                        || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16540                        || procState > ActivityManager.PROCESS_STATE_TOP);
16541                provi--) {
16542            ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
16543            for (int i = cpr.connections.size()-1;
16544                    i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
16545                            || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE
16546                            || procState > ActivityManager.PROCESS_STATE_TOP);
16547                    i--) {
16548                ContentProviderConnection conn = cpr.connections.get(i);
16549                ProcessRecord client = conn.client;
16550                if (client == app) {
16551                    // Being our own client is not interesting.
16552                    continue;
16553                }
16554                int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
16555                int clientProcState = client.curProcState;
16556                if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
16557                    // If the other app is cached for any reason, for purposes here
16558                    // we are going to consider it empty.
16559                    clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16560                }
16561                if (adj > clientAdj) {
16562                    if (app.hasShownUi && app != mHomeProcess
16563                            && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
16564                        app.adjType = "cch-ui-provider";
16565                    } else {
16566                        adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
16567                                ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
16568                        app.adjType = "provider";
16569                    }
16570                    app.cached &= client.cached;
16571                    app.adjTypeCode = ActivityManager.RunningAppProcessInfo
16572                            .REASON_PROVIDER_IN_USE;
16573                    app.adjSource = client;
16574                    app.adjSourceProcState = clientProcState;
16575                    app.adjTarget = cpr.name;
16576                }
16577                if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
16578                    if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
16579                        // Special handling of clients who are in the top state.
16580                        // We *may* want to consider this process to be in the
16581                        // top state as well, but only if there is not another
16582                        // reason for it to be running.  Being on the top is a
16583                        // special state, meaning you are specifically running
16584                        // for the current top app.  If the process is already
16585                        // running in the background for some other reason, it
16586                        // is more important to continue considering it to be
16587                        // in the background state.
16588                        mayBeTop = true;
16589                        clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
16590                    } else {
16591                        // Special handling for above-top states (persistent
16592                        // processes).  These should not bring the current process
16593                        // into the top state, since they are not on top.  Instead
16594                        // give them the best state after that.
16595                        clientProcState =
16596                                ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16597                    }
16598                }
16599                if (procState > clientProcState) {
16600                    procState = clientProcState;
16601                }
16602                if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
16603                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16604                }
16605            }
16606            // If the provider has external (non-framework) process
16607            // dependencies, ensure that its adjustment is at least
16608            // FOREGROUND_APP_ADJ.
16609            if (cpr.hasExternalProcessHandles()) {
16610                if (adj > ProcessList.FOREGROUND_APP_ADJ) {
16611                    adj = ProcessList.FOREGROUND_APP_ADJ;
16612                    schedGroup = Process.THREAD_GROUP_DEFAULT;
16613                    app.cached = false;
16614                    app.adjType = "provider";
16615                    app.adjTarget = cpr.name;
16616                }
16617                if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
16618                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16619                }
16620            }
16621        }
16622
16623        if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
16624            // A client of one of our services or providers is in the top state.  We
16625            // *may* want to be in the top state, but not if we are already running in
16626            // the background for some other reason.  For the decision here, we are going
16627            // to pick out a few specific states that we want to remain in when a client
16628            // is top (states that tend to be longer-term) and otherwise allow it to go
16629            // to the top state.
16630            switch (procState) {
16631                case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
16632                case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
16633                case ActivityManager.PROCESS_STATE_SERVICE:
16634                    // These all are longer-term states, so pull them up to the top
16635                    // of the background states, but not all the way to the top state.
16636                    procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
16637                    break;
16638                default:
16639                    // Otherwise, top is a better choice, so take it.
16640                    procState = ActivityManager.PROCESS_STATE_TOP;
16641                    break;
16642            }
16643        }
16644
16645        if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
16646            if (app.hasClientActivities) {
16647                // This is a cached process, but with client activities.  Mark it so.
16648                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
16649                app.adjType = "cch-client-act";
16650            } else if (app.treatLikeActivity) {
16651                // This is a cached process, but somebody wants us to treat it like it has
16652                // an activity, okay!
16653                procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
16654                app.adjType = "cch-as-act";
16655            }
16656        }
16657
16658        if (adj == ProcessList.SERVICE_ADJ) {
16659            if (doingAll) {
16660                app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
16661                mNewNumServiceProcs++;
16662                //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
16663                if (!app.serviceb) {
16664                    // This service isn't far enough down on the LRU list to
16665                    // normally be a B service, but if we are low on RAM and it
16666                    // is large we want to force it down since we would prefer to
16667                    // keep launcher over it.
16668                    if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
16669                            && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
16670                        app.serviceHighRam = true;
16671                        app.serviceb = true;
16672                        //Slog.i(TAG, "ADJ " + app + " high ram!");
16673                    } else {
16674                        mNewNumAServiceProcs++;
16675                        //Slog.i(TAG, "ADJ " + app + " not high ram!");
16676                    }
16677                } else {
16678                    app.serviceHighRam = false;
16679                }
16680            }
16681            if (app.serviceb) {
16682                adj = ProcessList.SERVICE_B_ADJ;
16683            }
16684        }
16685
16686        app.curRawAdj = adj;
16687
16688        //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
16689        //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
16690        if (adj > app.maxAdj) {
16691            adj = app.maxAdj;
16692            if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
16693                schedGroup = Process.THREAD_GROUP_DEFAULT;
16694            }
16695        }
16696
16697        // Do final modification to adj.  Everything we do between here and applying
16698        // the final setAdj must be done in this function, because we will also use
16699        // it when computing the final cached adj later.  Note that we don't need to
16700        // worry about this for max adj above, since max adj will always be used to
16701        // keep it out of the cached vaues.
16702        app.curAdj = app.modifyRawOomAdj(adj);
16703        app.curSchedGroup = schedGroup;
16704        app.curProcState = procState;
16705        app.foregroundActivities = foregroundActivities;
16706
16707        return app.curRawAdj;
16708    }
16709
16710    /**
16711     * Schedule PSS collection of a process.
16712     */
16713    void requestPssLocked(ProcessRecord proc, int procState) {
16714        if (mPendingPssProcesses.contains(proc)) {
16715            return;
16716        }
16717        if (mPendingPssProcesses.size() == 0) {
16718            mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16719        }
16720        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of: " + proc);
16721        proc.pssProcState = procState;
16722        mPendingPssProcesses.add(proc);
16723    }
16724
16725    /**
16726     * Schedule PSS collection of all processes.
16727     */
16728    void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
16729        if (!always) {
16730            if (now < (mLastFullPssTime +
16731                    (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
16732                return;
16733            }
16734        }
16735        if (DEBUG_PSS) Slog.d(TAG, "Requesting PSS of all procs!  memLowered=" + memLowered);
16736        mLastFullPssTime = now;
16737        mFullPssPending = true;
16738        mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
16739        mPendingPssProcesses.clear();
16740        for (int i=mLruProcesses.size()-1; i>=0; i--) {
16741            ProcessRecord app = mLruProcesses.get(i);
16742            if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
16743                app.pssProcState = app.setProcState;
16744                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
16745                        isSleeping(), now);
16746                mPendingPssProcesses.add(app);
16747            }
16748        }
16749        mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
16750    }
16751
16752    /**
16753     * Ask a given process to GC right now.
16754     */
16755    final void performAppGcLocked(ProcessRecord app) {
16756        try {
16757            app.lastRequestedGc = SystemClock.uptimeMillis();
16758            if (app.thread != null) {
16759                if (app.reportLowMemory) {
16760                    app.reportLowMemory = false;
16761                    app.thread.scheduleLowMemory();
16762                } else {
16763                    app.thread.processInBackground();
16764                }
16765            }
16766        } catch (Exception e) {
16767            // whatever.
16768        }
16769    }
16770
16771    /**
16772     * Returns true if things are idle enough to perform GCs.
16773     */
16774    private final boolean canGcNowLocked() {
16775        boolean processingBroadcasts = false;
16776        for (BroadcastQueue q : mBroadcastQueues) {
16777            if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
16778                processingBroadcasts = true;
16779            }
16780        }
16781        return !processingBroadcasts
16782                && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
16783    }
16784
16785    /**
16786     * Perform GCs on all processes that are waiting for it, but only
16787     * if things are idle.
16788     */
16789    final void performAppGcsLocked() {
16790        final int N = mProcessesToGc.size();
16791        if (N <= 0) {
16792            return;
16793        }
16794        if (canGcNowLocked()) {
16795            while (mProcessesToGc.size() > 0) {
16796                ProcessRecord proc = mProcessesToGc.remove(0);
16797                if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
16798                    if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
16799                            <= SystemClock.uptimeMillis()) {
16800                        // To avoid spamming the system, we will GC processes one
16801                        // at a time, waiting a few seconds between each.
16802                        performAppGcLocked(proc);
16803                        scheduleAppGcsLocked();
16804                        return;
16805                    } else {
16806                        // It hasn't been long enough since we last GCed this
16807                        // process...  put it in the list to wait for its time.
16808                        addProcessToGcListLocked(proc);
16809                        break;
16810                    }
16811                }
16812            }
16813
16814            scheduleAppGcsLocked();
16815        }
16816    }
16817
16818    /**
16819     * If all looks good, perform GCs on all processes waiting for them.
16820     */
16821    final void performAppGcsIfAppropriateLocked() {
16822        if (canGcNowLocked()) {
16823            performAppGcsLocked();
16824            return;
16825        }
16826        // Still not idle, wait some more.
16827        scheduleAppGcsLocked();
16828    }
16829
16830    /**
16831     * Schedule the execution of all pending app GCs.
16832     */
16833    final void scheduleAppGcsLocked() {
16834        mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
16835
16836        if (mProcessesToGc.size() > 0) {
16837            // Schedule a GC for the time to the next process.
16838            ProcessRecord proc = mProcessesToGc.get(0);
16839            Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
16840
16841            long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
16842            long now = SystemClock.uptimeMillis();
16843            if (when < (now+GC_TIMEOUT)) {
16844                when = now + GC_TIMEOUT;
16845            }
16846            mHandler.sendMessageAtTime(msg, when);
16847        }
16848    }
16849
16850    /**
16851     * Add a process to the array of processes waiting to be GCed.  Keeps the
16852     * list in sorted order by the last GC time.  The process can't already be
16853     * on the list.
16854     */
16855    final void addProcessToGcListLocked(ProcessRecord proc) {
16856        boolean added = false;
16857        for (int i=mProcessesToGc.size()-1; i>=0; i--) {
16858            if (mProcessesToGc.get(i).lastRequestedGc <
16859                    proc.lastRequestedGc) {
16860                added = true;
16861                mProcessesToGc.add(i+1, proc);
16862                break;
16863            }
16864        }
16865        if (!added) {
16866            mProcessesToGc.add(0, proc);
16867        }
16868    }
16869
16870    /**
16871     * Set up to ask a process to GC itself.  This will either do it
16872     * immediately, or put it on the list of processes to gc the next
16873     * time things are idle.
16874     */
16875    final void scheduleAppGcLocked(ProcessRecord app) {
16876        long now = SystemClock.uptimeMillis();
16877        if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
16878            return;
16879        }
16880        if (!mProcessesToGc.contains(app)) {
16881            addProcessToGcListLocked(app);
16882            scheduleAppGcsLocked();
16883        }
16884    }
16885
16886    final void checkExcessivePowerUsageLocked(boolean doKills) {
16887        updateCpuStatsNow();
16888
16889        BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16890        boolean doWakeKills = doKills;
16891        boolean doCpuKills = doKills;
16892        if (mLastPowerCheckRealtime == 0) {
16893            doWakeKills = false;
16894        }
16895        if (mLastPowerCheckUptime == 0) {
16896            doCpuKills = false;
16897        }
16898        if (stats.isScreenOn()) {
16899            doWakeKills = false;
16900        }
16901        final long curRealtime = SystemClock.elapsedRealtime();
16902        final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
16903        final long curUptime = SystemClock.uptimeMillis();
16904        final long uptimeSince = curUptime - mLastPowerCheckUptime;
16905        mLastPowerCheckRealtime = curRealtime;
16906        mLastPowerCheckUptime = curUptime;
16907        if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
16908            doWakeKills = false;
16909        }
16910        if (uptimeSince < CPU_MIN_CHECK_DURATION) {
16911            doCpuKills = false;
16912        }
16913        int i = mLruProcesses.size();
16914        while (i > 0) {
16915            i--;
16916            ProcessRecord app = mLruProcesses.get(i);
16917            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
16918                long wtime;
16919                synchronized (stats) {
16920                    wtime = stats.getProcessWakeTime(app.info.uid,
16921                            app.pid, curRealtime);
16922                }
16923                long wtimeUsed = wtime - app.lastWakeTime;
16924                long cputimeUsed = app.curCpuTime - app.lastCpuTime;
16925                if (DEBUG_POWER) {
16926                    StringBuilder sb = new StringBuilder(128);
16927                    sb.append("Wake for ");
16928                    app.toShortString(sb);
16929                    sb.append(": over ");
16930                    TimeUtils.formatDuration(realtimeSince, sb);
16931                    sb.append(" used ");
16932                    TimeUtils.formatDuration(wtimeUsed, sb);
16933                    sb.append(" (");
16934                    sb.append((wtimeUsed*100)/realtimeSince);
16935                    sb.append("%)");
16936                    Slog.i(TAG, sb.toString());
16937                    sb.setLength(0);
16938                    sb.append("CPU for ");
16939                    app.toShortString(sb);
16940                    sb.append(": over ");
16941                    TimeUtils.formatDuration(uptimeSince, sb);
16942                    sb.append(" used ");
16943                    TimeUtils.formatDuration(cputimeUsed, sb);
16944                    sb.append(" (");
16945                    sb.append((cputimeUsed*100)/uptimeSince);
16946                    sb.append("%)");
16947                    Slog.i(TAG, sb.toString());
16948                }
16949                // If a process has held a wake lock for more
16950                // than 50% of the time during this period,
16951                // that sounds bad.  Kill!
16952                if (doWakeKills && realtimeSince > 0
16953                        && ((wtimeUsed*100)/realtimeSince) >= 50) {
16954                    synchronized (stats) {
16955                        stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
16956                                realtimeSince, wtimeUsed);
16957                    }
16958                    app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
16959                    app.baseProcessTracker.reportExcessiveWake(app.pkgList);
16960                } else if (doCpuKills && uptimeSince > 0
16961                        && ((cputimeUsed*100)/uptimeSince) >= 25) {
16962                    synchronized (stats) {
16963                        stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
16964                                uptimeSince, cputimeUsed);
16965                    }
16966                    app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
16967                    app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
16968                } else {
16969                    app.lastWakeTime = wtime;
16970                    app.lastCpuTime = app.curCpuTime;
16971                }
16972            }
16973        }
16974    }
16975
16976    private final boolean applyOomAdjLocked(ProcessRecord app,
16977            ProcessRecord TOP_APP, boolean doingAll, long now) {
16978        boolean success = true;
16979
16980        if (app.curRawAdj != app.setRawAdj) {
16981            app.setRawAdj = app.curRawAdj;
16982        }
16983
16984        int changes = 0;
16985
16986        if (app.curAdj != app.setAdj) {
16987            ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
16988            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
16989                TAG, "Set " + app.pid + " " + app.processName +
16990                " adj " + app.curAdj + ": " + app.adjType);
16991            app.setAdj = app.curAdj;
16992        }
16993
16994        if (app.setSchedGroup != app.curSchedGroup) {
16995            app.setSchedGroup = app.curSchedGroup;
16996            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
16997                    "Setting process group of " + app.processName
16998                    + " to " + app.curSchedGroup);
16999            if (app.waitingToKill != null &&
17000                    app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
17001                app.kill(app.waitingToKill, true);
17002                success = false;
17003            } else {
17004                if (true) {
17005                    long oldId = Binder.clearCallingIdentity();
17006                    try {
17007                        Process.setProcessGroup(app.pid, app.curSchedGroup);
17008                    } catch (Exception e) {
17009                        Slog.w(TAG, "Failed setting process group of " + app.pid
17010                                + " to " + app.curSchedGroup);
17011                        e.printStackTrace();
17012                    } finally {
17013                        Binder.restoreCallingIdentity(oldId);
17014                    }
17015                } else {
17016                    if (app.thread != null) {
17017                        try {
17018                            app.thread.setSchedulingGroup(app.curSchedGroup);
17019                        } catch (RemoteException e) {
17020                        }
17021                    }
17022                }
17023                Process.setSwappiness(app.pid,
17024                        app.curSchedGroup <= Process.THREAD_GROUP_BG_NONINTERACTIVE);
17025            }
17026        }
17027        if (app.repForegroundActivities != app.foregroundActivities) {
17028            app.repForegroundActivities = app.foregroundActivities;
17029            changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
17030        }
17031        if (app.repProcState != app.curProcState) {
17032            app.repProcState = app.curProcState;
17033            changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
17034            if (app.thread != null) {
17035                try {
17036                    if (false) {
17037                        //RuntimeException h = new RuntimeException("here");
17038                        Slog.i(TAG, "Sending new process state " + app.repProcState
17039                                + " to " + app /*, h*/);
17040                    }
17041                    app.thread.setProcessState(app.repProcState);
17042                } catch (RemoteException e) {
17043                }
17044            }
17045        }
17046        if (app.setProcState < 0 || ProcessList.procStatesDifferForMem(app.curProcState,
17047                app.setProcState)) {
17048            app.lastStateTime = now;
17049            app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
17050                    isSleeping(), now);
17051            if (DEBUG_PSS) Slog.d(TAG, "Process state change from "
17052                    + ProcessList.makeProcStateString(app.setProcState) + " to "
17053                    + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
17054                    + (app.nextPssTime-now) + ": " + app);
17055        } else {
17056            if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
17057                    && now > (app.lastStateTime+ProcessList.PSS_MIN_TIME_FROM_STATE_CHANGE))) {
17058                requestPssLocked(app, app.setProcState);
17059                app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
17060                        isSleeping(), now);
17061            } else if (false && DEBUG_PSS) {
17062                Slog.d(TAG, "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
17063            }
17064        }
17065        if (app.setProcState != app.curProcState) {
17066            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17067                    "Proc state change of " + app.processName
17068                    + " to " + app.curProcState);
17069            boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
17070            boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
17071            if (setImportant && !curImportant) {
17072                // This app is no longer something we consider important enough to allow to
17073                // use arbitrary amounts of battery power.  Note
17074                // its current wake lock time to later know to kill it if
17075                // it is not behaving well.
17076                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17077                synchronized (stats) {
17078                    app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
17079                            app.pid, SystemClock.elapsedRealtime());
17080                }
17081                app.lastCpuTime = app.curCpuTime;
17082
17083            }
17084            app.setProcState = app.curProcState;
17085            if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
17086                app.notCachedSinceIdle = false;
17087            }
17088            if (!doingAll) {
17089                setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
17090            } else {
17091                app.procStateChanged = true;
17092            }
17093        }
17094
17095        if (changes != 0) {
17096            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
17097            int i = mPendingProcessChanges.size()-1;
17098            ProcessChangeItem item = null;
17099            while (i >= 0) {
17100                item = mPendingProcessChanges.get(i);
17101                if (item.pid == app.pid) {
17102                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
17103                    break;
17104                }
17105                i--;
17106            }
17107            if (i < 0) {
17108                // No existing item in pending changes; need a new one.
17109                final int NA = mAvailProcessChanges.size();
17110                if (NA > 0) {
17111                    item = mAvailProcessChanges.remove(NA-1);
17112                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
17113                } else {
17114                    item = new ProcessChangeItem();
17115                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
17116                }
17117                item.changes = 0;
17118                item.pid = app.pid;
17119                item.uid = app.info.uid;
17120                if (mPendingProcessChanges.size() == 0) {
17121                    if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
17122                            "*** Enqueueing dispatch processes changed!");
17123                    mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
17124                }
17125                mPendingProcessChanges.add(item);
17126            }
17127            item.changes |= changes;
17128            item.processState = app.repProcState;
17129            item.foregroundActivities = app.repForegroundActivities;
17130            if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
17131                    + Integer.toHexString(System.identityHashCode(item))
17132                    + " " + app.toShortString() + ": changes=" + item.changes
17133                    + " procState=" + item.processState
17134                    + " foreground=" + item.foregroundActivities
17135                    + " type=" + app.adjType + " source=" + app.adjSource
17136                    + " target=" + app.adjTarget);
17137        }
17138
17139        return success;
17140    }
17141
17142    private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
17143        if (proc.thread != null) {
17144            if (proc.baseProcessTracker != null) {
17145                proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
17146            }
17147            if (proc.repProcState >= 0) {
17148                mBatteryStatsService.noteProcessState(proc.processName, proc.info.uid,
17149                        proc.repProcState);
17150            }
17151        }
17152    }
17153
17154    private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
17155            ProcessRecord TOP_APP, boolean doingAll, long now) {
17156        if (app.thread == null) {
17157            return false;
17158        }
17159
17160        computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
17161
17162        return applyOomAdjLocked(app, TOP_APP, doingAll, now);
17163    }
17164
17165    final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
17166            boolean oomAdj) {
17167        if (isForeground != proc.foregroundServices) {
17168            proc.foregroundServices = isForeground;
17169            ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
17170                    proc.info.uid);
17171            if (isForeground) {
17172                if (curProcs == null) {
17173                    curProcs = new ArrayList<ProcessRecord>();
17174                    mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
17175                }
17176                if (!curProcs.contains(proc)) {
17177                    curProcs.add(proc);
17178                    mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
17179                            proc.info.packageName, proc.info.uid);
17180                }
17181            } else {
17182                if (curProcs != null) {
17183                    if (curProcs.remove(proc)) {
17184                        mBatteryStatsService.noteEvent(
17185                                BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
17186                                proc.info.packageName, proc.info.uid);
17187                        if (curProcs.size() <= 0) {
17188                            mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
17189                        }
17190                    }
17191                }
17192            }
17193            if (oomAdj) {
17194                updateOomAdjLocked();
17195            }
17196        }
17197    }
17198
17199    private final ActivityRecord resumedAppLocked() {
17200        ActivityRecord act = mStackSupervisor.resumedAppLocked();
17201        String pkg;
17202        int uid;
17203        if (act != null) {
17204            pkg = act.packageName;
17205            uid = act.info.applicationInfo.uid;
17206        } else {
17207            pkg = null;
17208            uid = -1;
17209        }
17210        // Has the UID or resumed package name changed?
17211        if (uid != mCurResumedUid || (pkg != mCurResumedPackage
17212                && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
17213            if (mCurResumedPackage != null) {
17214                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
17215                        mCurResumedPackage, mCurResumedUid);
17216            }
17217            mCurResumedPackage = pkg;
17218            mCurResumedUid = uid;
17219            if (mCurResumedPackage != null) {
17220                mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
17221                        mCurResumedPackage, mCurResumedUid);
17222            }
17223        }
17224        return act;
17225    }
17226
17227    final boolean updateOomAdjLocked(ProcessRecord app) {
17228        final ActivityRecord TOP_ACT = resumedAppLocked();
17229        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17230        final boolean wasCached = app.cached;
17231
17232        mAdjSeq++;
17233
17234        // This is the desired cached adjusment we want to tell it to use.
17235        // If our app is currently cached, we know it, and that is it.  Otherwise,
17236        // we don't know it yet, and it needs to now be cached we will then
17237        // need to do a complete oom adj.
17238        final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
17239                ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
17240        boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
17241                SystemClock.uptimeMillis());
17242        if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
17243            // Changed to/from cached state, so apps after it in the LRU
17244            // list may also be changed.
17245            updateOomAdjLocked();
17246        }
17247        return success;
17248    }
17249
17250    final void updateOomAdjLocked() {
17251        final ActivityRecord TOP_ACT = resumedAppLocked();
17252        final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
17253        final long now = SystemClock.uptimeMillis();
17254        final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
17255        final int N = mLruProcesses.size();
17256
17257        if (false) {
17258            RuntimeException e = new RuntimeException();
17259            e.fillInStackTrace();
17260            Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
17261        }
17262
17263        mAdjSeq++;
17264        mNewNumServiceProcs = 0;
17265        mNewNumAServiceProcs = 0;
17266
17267        final int emptyProcessLimit;
17268        final int cachedProcessLimit;
17269        if (mProcessLimit <= 0) {
17270            emptyProcessLimit = cachedProcessLimit = 0;
17271        } else if (mProcessLimit == 1) {
17272            emptyProcessLimit = 1;
17273            cachedProcessLimit = 0;
17274        } else {
17275            emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
17276            cachedProcessLimit = mProcessLimit - emptyProcessLimit;
17277        }
17278
17279        // Let's determine how many processes we have running vs.
17280        // how many slots we have for background processes; we may want
17281        // to put multiple processes in a slot of there are enough of
17282        // them.
17283        int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
17284                - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
17285        int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
17286        if (numEmptyProcs > cachedProcessLimit) {
17287            // If there are more empty processes than our limit on cached
17288            // processes, then use the cached process limit for the factor.
17289            // This ensures that the really old empty processes get pushed
17290            // down to the bottom, so if we are running low on memory we will
17291            // have a better chance at keeping around more cached processes
17292            // instead of a gazillion empty processes.
17293            numEmptyProcs = cachedProcessLimit;
17294        }
17295        int emptyFactor = numEmptyProcs/numSlots;
17296        if (emptyFactor < 1) emptyFactor = 1;
17297        int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
17298        if (cachedFactor < 1) cachedFactor = 1;
17299        int stepCached = 0;
17300        int stepEmpty = 0;
17301        int numCached = 0;
17302        int numEmpty = 0;
17303        int numTrimming = 0;
17304
17305        mNumNonCachedProcs = 0;
17306        mNumCachedHiddenProcs = 0;
17307
17308        // First update the OOM adjustment for each of the
17309        // application processes based on their current state.
17310        int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
17311        int nextCachedAdj = curCachedAdj+1;
17312        int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
17313        int nextEmptyAdj = curEmptyAdj+2;
17314        for (int i=N-1; i>=0; i--) {
17315            ProcessRecord app = mLruProcesses.get(i);
17316            if (!app.killedByAm && app.thread != null) {
17317                app.procStateChanged = false;
17318                computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
17319
17320                // If we haven't yet assigned the final cached adj
17321                // to the process, do that now.
17322                if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
17323                    switch (app.curProcState) {
17324                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17325                        case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17326                            // This process is a cached process holding activities...
17327                            // assign it the next cached value for that type, and then
17328                            // step that cached level.
17329                            app.curRawAdj = curCachedAdj;
17330                            app.curAdj = app.modifyRawOomAdj(curCachedAdj);
17331                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning activity LRU #" + i
17332                                    + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
17333                                    + ")");
17334                            if (curCachedAdj != nextCachedAdj) {
17335                                stepCached++;
17336                                if (stepCached >= cachedFactor) {
17337                                    stepCached = 0;
17338                                    curCachedAdj = nextCachedAdj;
17339                                    nextCachedAdj += 2;
17340                                    if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17341                                        nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
17342                                    }
17343                                }
17344                            }
17345                            break;
17346                        default:
17347                            // For everything else, assign next empty cached process
17348                            // level and bump that up.  Note that this means that
17349                            // long-running services that have dropped down to the
17350                            // cached level will be treated as empty (since their process
17351                            // state is still as a service), which is what we want.
17352                            app.curRawAdj = curEmptyAdj;
17353                            app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
17354                            if (DEBUG_LRU && false) Slog.d(TAG, "Assigning empty LRU #" + i
17355                                    + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
17356                                    + ")");
17357                            if (curEmptyAdj != nextEmptyAdj) {
17358                                stepEmpty++;
17359                                if (stepEmpty >= emptyFactor) {
17360                                    stepEmpty = 0;
17361                                    curEmptyAdj = nextEmptyAdj;
17362                                    nextEmptyAdj += 2;
17363                                    if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
17364                                        nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
17365                                    }
17366                                }
17367                            }
17368                            break;
17369                    }
17370                }
17371
17372                applyOomAdjLocked(app, TOP_APP, true, now);
17373
17374                // Count the number of process types.
17375                switch (app.curProcState) {
17376                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
17377                    case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
17378                        mNumCachedHiddenProcs++;
17379                        numCached++;
17380                        if (numCached > cachedProcessLimit) {
17381                            app.kill("cached #" + numCached, true);
17382                        }
17383                        break;
17384                    case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
17385                        if (numEmpty > ProcessList.TRIM_EMPTY_APPS
17386                                && app.lastActivityTime < oldTime) {
17387                            app.kill("empty for "
17388                                    + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
17389                                    / 1000) + "s", true);
17390                        } else {
17391                            numEmpty++;
17392                            if (numEmpty > emptyProcessLimit) {
17393                                app.kill("empty #" + numEmpty, true);
17394                            }
17395                        }
17396                        break;
17397                    default:
17398                        mNumNonCachedProcs++;
17399                        break;
17400                }
17401
17402                if (app.isolated && app.services.size() <= 0) {
17403                    // If this is an isolated process, and there are no
17404                    // services running in it, then the process is no longer
17405                    // needed.  We agressively kill these because we can by
17406                    // definition not re-use the same process again, and it is
17407                    // good to avoid having whatever code was running in them
17408                    // left sitting around after no longer needed.
17409                    app.kill("isolated not needed", true);
17410                }
17411
17412                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17413                        && !app.killedByAm) {
17414                    numTrimming++;
17415                }
17416            }
17417        }
17418
17419        mNumServiceProcs = mNewNumServiceProcs;
17420
17421        // Now determine the memory trimming level of background processes.
17422        // Unfortunately we need to start at the back of the list to do this
17423        // properly.  We only do this if the number of background apps we
17424        // are managing to keep around is less than half the maximum we desire;
17425        // if we are keeping a good number around, we'll let them use whatever
17426        // memory they want.
17427        final int numCachedAndEmpty = numCached + numEmpty;
17428        int memFactor;
17429        if (numCached <= ProcessList.TRIM_CACHED_APPS
17430                && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
17431            if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
17432                memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
17433            } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
17434                memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
17435            } else {
17436                memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
17437            }
17438        } else {
17439            memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
17440        }
17441        // We always allow the memory level to go up (better).  We only allow it to go
17442        // down if we are in a state where that is allowed, *and* the total number of processes
17443        // has gone down since last time.
17444        if (DEBUG_OOM_ADJ) Slog.d(TAG, "oom: memFactor=" + memFactor + " last=" + mLastMemoryLevel
17445                + " allowLow=" + mAllowLowerMemLevel + " numProcs=" + mLruProcesses.size()
17446                + " last=" + mLastNumProcesses);
17447        if (memFactor > mLastMemoryLevel) {
17448            if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
17449                memFactor = mLastMemoryLevel;
17450                if (DEBUG_OOM_ADJ) Slog.d(TAG, "Keeping last mem factor!");
17451            }
17452        }
17453        mLastMemoryLevel = memFactor;
17454        mLastNumProcesses = mLruProcesses.size();
17455        boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
17456        final int trackerMemFactor = mProcessStats.getMemFactorLocked();
17457        if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
17458            if (mLowRamStartTime == 0) {
17459                mLowRamStartTime = now;
17460            }
17461            int step = 0;
17462            int fgTrimLevel;
17463            switch (memFactor) {
17464                case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
17465                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
17466                    break;
17467                case ProcessStats.ADJ_MEM_FACTOR_LOW:
17468                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
17469                    break;
17470                default:
17471                    fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
17472                    break;
17473            }
17474            int factor = numTrimming/3;
17475            int minFactor = 2;
17476            if (mHomeProcess != null) minFactor++;
17477            if (mPreviousProcess != null) minFactor++;
17478            if (factor < minFactor) factor = minFactor;
17479            int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
17480            for (int i=N-1; i>=0; i--) {
17481                ProcessRecord app = mLruProcesses.get(i);
17482                if (allChanged || app.procStateChanged) {
17483                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17484                    app.procStateChanged = false;
17485                }
17486                if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
17487                        && !app.killedByAm) {
17488                    if (app.trimMemoryLevel < curLevel && app.thread != null) {
17489                        try {
17490                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17491                                    "Trimming memory of " + app.processName
17492                                    + " to " + curLevel);
17493                            app.thread.scheduleTrimMemory(curLevel);
17494                        } catch (RemoteException e) {
17495                        }
17496                        if (false) {
17497                            // For now we won't do this; our memory trimming seems
17498                            // to be good enough at this point that destroying
17499                            // activities causes more harm than good.
17500                            if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
17501                                    && app != mHomeProcess && app != mPreviousProcess) {
17502                                // Need to do this on its own message because the stack may not
17503                                // be in a consistent state at this point.
17504                                // For these apps we will also finish their activities
17505                                // to help them free memory.
17506                                mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
17507                            }
17508                        }
17509                    }
17510                    app.trimMemoryLevel = curLevel;
17511                    step++;
17512                    if (step >= factor) {
17513                        step = 0;
17514                        switch (curLevel) {
17515                            case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
17516                                curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
17517                                break;
17518                            case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
17519                                curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17520                                break;
17521                        }
17522                    }
17523                } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
17524                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
17525                            && app.thread != null) {
17526                        try {
17527                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17528                                    "Trimming memory of heavy-weight " + app.processName
17529                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17530                            app.thread.scheduleTrimMemory(
17531                                    ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
17532                        } catch (RemoteException e) {
17533                        }
17534                    }
17535                    app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
17536                } else {
17537                    if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17538                            || app.systemNoUi) && app.pendingUiClean) {
17539                        // If this application is now in the background and it
17540                        // had done UI, then give it the special trim level to
17541                        // have it free UI resources.
17542                        final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
17543                        if (app.trimMemoryLevel < level && app.thread != null) {
17544                            try {
17545                                if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17546                                        "Trimming memory of bg-ui " + app.processName
17547                                        + " to " + level);
17548                                app.thread.scheduleTrimMemory(level);
17549                            } catch (RemoteException e) {
17550                            }
17551                        }
17552                        app.pendingUiClean = false;
17553                    }
17554                    if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
17555                        try {
17556                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17557                                    "Trimming memory of fg " + app.processName
17558                                    + " to " + fgTrimLevel);
17559                            app.thread.scheduleTrimMemory(fgTrimLevel);
17560                        } catch (RemoteException e) {
17561                        }
17562                    }
17563                    app.trimMemoryLevel = fgTrimLevel;
17564                }
17565            }
17566        } else {
17567            if (mLowRamStartTime != 0) {
17568                mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
17569                mLowRamStartTime = 0;
17570            }
17571            for (int i=N-1; i>=0; i--) {
17572                ProcessRecord app = mLruProcesses.get(i);
17573                if (allChanged || app.procStateChanged) {
17574                    setProcessTrackerStateLocked(app, trackerMemFactor, now);
17575                    app.procStateChanged = false;
17576                }
17577                if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
17578                        || app.systemNoUi) && app.pendingUiClean) {
17579                    if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
17580                            && app.thread != null) {
17581                        try {
17582                            if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
17583                                    "Trimming memory of ui hidden " + app.processName
17584                                    + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17585                            app.thread.scheduleTrimMemory(
17586                                    ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
17587                        } catch (RemoteException e) {
17588                        }
17589                    }
17590                    app.pendingUiClean = false;
17591                }
17592                app.trimMemoryLevel = 0;
17593            }
17594        }
17595
17596        if (mAlwaysFinishActivities) {
17597            // Need to do this on its own message because the stack may not
17598            // be in a consistent state at this point.
17599            mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
17600        }
17601
17602        if (allChanged) {
17603            requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
17604        }
17605
17606        if (mProcessStats.shouldWriteNowLocked(now)) {
17607            mHandler.post(new Runnable() {
17608                @Override public void run() {
17609                    synchronized (ActivityManagerService.this) {
17610                        mProcessStats.writeStateAsyncLocked();
17611                    }
17612                }
17613            });
17614        }
17615
17616        if (DEBUG_OOM_ADJ) {
17617            Slog.d(TAG, "Did OOM ADJ in " + (SystemClock.uptimeMillis()-now) + "ms");
17618        }
17619    }
17620
17621    final void trimApplications() {
17622        synchronized (this) {
17623            int i;
17624
17625            // First remove any unused application processes whose package
17626            // has been removed.
17627            for (i=mRemovedProcesses.size()-1; i>=0; i--) {
17628                final ProcessRecord app = mRemovedProcesses.get(i);
17629                if (app.activities.size() == 0
17630                        && app.curReceiver == null && app.services.size() == 0) {
17631                    Slog.i(
17632                        TAG, "Exiting empty application process "
17633                        + app.processName + " ("
17634                        + (app.thread != null ? app.thread.asBinder() : null)
17635                        + ")\n");
17636                    if (app.pid > 0 && app.pid != MY_PID) {
17637                        app.kill("empty", false);
17638                    } else {
17639                        try {
17640                            app.thread.scheduleExit();
17641                        } catch (Exception e) {
17642                            // Ignore exceptions.
17643                        }
17644                    }
17645                    cleanUpApplicationRecordLocked(app, false, true, -1);
17646                    mRemovedProcesses.remove(i);
17647
17648                    if (app.persistent) {
17649                        addAppLocked(app.info, false, null /* ABI override */);
17650                    }
17651                }
17652            }
17653
17654            // Now update the oom adj for all processes.
17655            updateOomAdjLocked();
17656        }
17657    }
17658
17659    /** This method sends the specified signal to each of the persistent apps */
17660    public void signalPersistentProcesses(int sig) throws RemoteException {
17661        if (sig != Process.SIGNAL_USR1) {
17662            throw new SecurityException("Only SIGNAL_USR1 is allowed");
17663        }
17664
17665        synchronized (this) {
17666            if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
17667                    != PackageManager.PERMISSION_GRANTED) {
17668                throw new SecurityException("Requires permission "
17669                        + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
17670            }
17671
17672            for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17673                ProcessRecord r = mLruProcesses.get(i);
17674                if (r.thread != null && r.persistent) {
17675                    Process.sendSignal(r.pid, sig);
17676                }
17677            }
17678        }
17679    }
17680
17681    private void stopProfilerLocked(ProcessRecord proc, int profileType) {
17682        if (proc == null || proc == mProfileProc) {
17683            proc = mProfileProc;
17684            profileType = mProfileType;
17685            clearProfilerLocked();
17686        }
17687        if (proc == null) {
17688            return;
17689        }
17690        try {
17691            proc.thread.profilerControl(false, null, profileType);
17692        } catch (RemoteException e) {
17693            throw new IllegalStateException("Process disappeared");
17694        }
17695    }
17696
17697    private void clearProfilerLocked() {
17698        if (mProfileFd != null) {
17699            try {
17700                mProfileFd.close();
17701            } catch (IOException e) {
17702            }
17703        }
17704        mProfileApp = null;
17705        mProfileProc = null;
17706        mProfileFile = null;
17707        mProfileType = 0;
17708        mAutoStopProfiler = false;
17709        mSamplingInterval = 0;
17710    }
17711
17712    public boolean profileControl(String process, int userId, boolean start,
17713            ProfilerInfo profilerInfo, int profileType) throws RemoteException {
17714
17715        try {
17716            synchronized (this) {
17717                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17718                // its own permission.
17719                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17720                        != PackageManager.PERMISSION_GRANTED) {
17721                    throw new SecurityException("Requires permission "
17722                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17723                }
17724
17725                if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
17726                    throw new IllegalArgumentException("null profile info or fd");
17727                }
17728
17729                ProcessRecord proc = null;
17730                if (process != null) {
17731                    proc = findProcessLocked(process, userId, "profileControl");
17732                }
17733
17734                if (start && (proc == null || proc.thread == null)) {
17735                    throw new IllegalArgumentException("Unknown process: " + process);
17736                }
17737
17738                if (start) {
17739                    stopProfilerLocked(null, 0);
17740                    setProfileApp(proc.info, proc.processName, profilerInfo);
17741                    mProfileProc = proc;
17742                    mProfileType = profileType;
17743                    ParcelFileDescriptor fd = profilerInfo.profileFd;
17744                    try {
17745                        fd = fd.dup();
17746                    } catch (IOException e) {
17747                        fd = null;
17748                    }
17749                    profilerInfo.profileFd = fd;
17750                    proc.thread.profilerControl(start, profilerInfo, profileType);
17751                    fd = null;
17752                    mProfileFd = null;
17753                } else {
17754                    stopProfilerLocked(proc, profileType);
17755                    if (profilerInfo != null && profilerInfo.profileFd != null) {
17756                        try {
17757                            profilerInfo.profileFd.close();
17758                        } catch (IOException e) {
17759                        }
17760                    }
17761                }
17762
17763                return true;
17764            }
17765        } catch (RemoteException e) {
17766            throw new IllegalStateException("Process disappeared");
17767        } finally {
17768            if (profilerInfo != null && profilerInfo.profileFd != null) {
17769                try {
17770                    profilerInfo.profileFd.close();
17771                } catch (IOException e) {
17772                }
17773            }
17774        }
17775    }
17776
17777    private ProcessRecord findProcessLocked(String process, int userId, String callName) {
17778        userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17779                userId, true, ALLOW_FULL_ONLY, callName, null);
17780        ProcessRecord proc = null;
17781        try {
17782            int pid = Integer.parseInt(process);
17783            synchronized (mPidsSelfLocked) {
17784                proc = mPidsSelfLocked.get(pid);
17785            }
17786        } catch (NumberFormatException e) {
17787        }
17788
17789        if (proc == null) {
17790            ArrayMap<String, SparseArray<ProcessRecord>> all
17791                    = mProcessNames.getMap();
17792            SparseArray<ProcessRecord> procs = all.get(process);
17793            if (procs != null && procs.size() > 0) {
17794                proc = procs.valueAt(0);
17795                if (userId != UserHandle.USER_ALL && proc.userId != userId) {
17796                    for (int i=1; i<procs.size(); i++) {
17797                        ProcessRecord thisProc = procs.valueAt(i);
17798                        if (thisProc.userId == userId) {
17799                            proc = thisProc;
17800                            break;
17801                        }
17802                    }
17803                }
17804            }
17805        }
17806
17807        return proc;
17808    }
17809
17810    public boolean dumpHeap(String process, int userId, boolean managed,
17811            String path, ParcelFileDescriptor fd) throws RemoteException {
17812
17813        try {
17814            synchronized (this) {
17815                // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
17816                // its own permission (same as profileControl).
17817                if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
17818                        != PackageManager.PERMISSION_GRANTED) {
17819                    throw new SecurityException("Requires permission "
17820                            + android.Manifest.permission.SET_ACTIVITY_WATCHER);
17821                }
17822
17823                if (fd == null) {
17824                    throw new IllegalArgumentException("null fd");
17825                }
17826
17827                ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
17828                if (proc == null || proc.thread == null) {
17829                    throw new IllegalArgumentException("Unknown process: " + process);
17830                }
17831
17832                boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
17833                if (!isDebuggable) {
17834                    if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
17835                        throw new SecurityException("Process not debuggable: " + proc);
17836                    }
17837                }
17838
17839                proc.thread.dumpHeap(managed, path, fd);
17840                fd = null;
17841                return true;
17842            }
17843        } catch (RemoteException e) {
17844            throw new IllegalStateException("Process disappeared");
17845        } finally {
17846            if (fd != null) {
17847                try {
17848                    fd.close();
17849                } catch (IOException e) {
17850                }
17851            }
17852        }
17853    }
17854
17855    /** In this method we try to acquire our lock to make sure that we have not deadlocked */
17856    public void monitor() {
17857        synchronized (this) { }
17858    }
17859
17860    void onCoreSettingsChange(Bundle settings) {
17861        for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
17862            ProcessRecord processRecord = mLruProcesses.get(i);
17863            try {
17864                if (processRecord.thread != null) {
17865                    processRecord.thread.setCoreSettings(settings);
17866                }
17867            } catch (RemoteException re) {
17868                /* ignore */
17869            }
17870        }
17871    }
17872
17873    // Multi-user methods
17874
17875    /**
17876     * Start user, if its not already running, but don't bring it to foreground.
17877     */
17878    @Override
17879    public boolean startUserInBackground(final int userId) {
17880        return startUser(userId, /* foreground */ false);
17881    }
17882
17883    /**
17884     * Start user, if its not already running, and bring it to foreground.
17885     */
17886    boolean startUserInForeground(final int userId, Dialog dlg) {
17887        boolean result = startUser(userId, /* foreground */ true);
17888        dlg.dismiss();
17889        return result;
17890    }
17891
17892    /**
17893     * Refreshes the list of users related to the current user when either a
17894     * user switch happens or when a new related user is started in the
17895     * background.
17896     */
17897    private void updateCurrentProfileIdsLocked() {
17898        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17899                mCurrentUserId, false /* enabledOnly */);
17900        int[] currentProfileIds = new int[profiles.size()]; // profiles will not be null
17901        for (int i = 0; i < currentProfileIds.length; i++) {
17902            currentProfileIds[i] = profiles.get(i).id;
17903        }
17904        mCurrentProfileIds = currentProfileIds;
17905
17906        synchronized (mUserProfileGroupIdsSelfLocked) {
17907            mUserProfileGroupIdsSelfLocked.clear();
17908            final List<UserInfo> users = getUserManagerLocked().getUsers(false);
17909            for (int i = 0; i < users.size(); i++) {
17910                UserInfo user = users.get(i);
17911                if (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID) {
17912                    mUserProfileGroupIdsSelfLocked.put(user.id, user.profileGroupId);
17913                }
17914            }
17915        }
17916    }
17917
17918    private Set getProfileIdsLocked(int userId) {
17919        Set userIds = new HashSet<Integer>();
17920        final List<UserInfo> profiles = getUserManagerLocked().getProfiles(
17921                userId, false /* enabledOnly */);
17922        for (UserInfo user : profiles) {
17923            userIds.add(Integer.valueOf(user.id));
17924        }
17925        return userIds;
17926    }
17927
17928    @Override
17929    public boolean switchUser(final int userId) {
17930        String userName;
17931        synchronized (this) {
17932            UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17933            if (userInfo == null) {
17934                Slog.w(TAG, "No user info for user #" + userId);
17935                return false;
17936            }
17937            if (userInfo.isManagedProfile()) {
17938                Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17939                return false;
17940            }
17941            userName = userInfo.name;
17942        }
17943        mHandler.removeMessages(START_USER_SWITCH_MSG);
17944        mHandler.sendMessage(mHandler.obtainMessage(START_USER_SWITCH_MSG, userId, 0, userName));
17945        return true;
17946    }
17947
17948    private void showUserSwitchDialog(int userId, String userName) {
17949        // The dialog will show and then initiate the user switch by calling startUserInForeground
17950        Dialog d = new UserSwitchingDialog(this, mContext, userId, userName,
17951                true /* above system */);
17952        d.show();
17953    }
17954
17955    private boolean startUser(final int userId, final boolean foreground) {
17956        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
17957                != PackageManager.PERMISSION_GRANTED) {
17958            String msg = "Permission Denial: switchUser() from pid="
17959                    + Binder.getCallingPid()
17960                    + ", uid=" + Binder.getCallingUid()
17961                    + " requires " + INTERACT_ACROSS_USERS_FULL;
17962            Slog.w(TAG, msg);
17963            throw new SecurityException(msg);
17964        }
17965
17966        if (DEBUG_MU) Slog.i(TAG_MU, "starting userid:" + userId + " fore:" + foreground);
17967
17968        final long ident = Binder.clearCallingIdentity();
17969        try {
17970            synchronized (this) {
17971                final int oldUserId = mCurrentUserId;
17972                if (oldUserId == userId) {
17973                    return true;
17974                }
17975
17976                mStackSupervisor.setLockTaskModeLocked(null, false);
17977
17978                final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
17979                if (userInfo == null) {
17980                    Slog.w(TAG, "No user info for user #" + userId);
17981                    return false;
17982                }
17983                if (foreground && userInfo.isManagedProfile()) {
17984                    Slog.w(TAG, "Cannot switch to User #" + userId + ": not a full user");
17985                    return false;
17986                }
17987
17988                if (foreground) {
17989                    mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
17990                            R.anim.screen_user_enter);
17991                }
17992
17993                boolean needStart = false;
17994
17995                // If the user we are switching to is not currently started, then
17996                // we need to start it now.
17997                if (mStartedUsers.get(userId) == null) {
17998                    mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
17999                    updateStartedUserArrayLocked();
18000                    needStart = true;
18001                }
18002
18003                final Integer userIdInt = Integer.valueOf(userId);
18004                mUserLru.remove(userIdInt);
18005                mUserLru.add(userIdInt);
18006
18007                if (foreground) {
18008                    mCurrentUserId = userId;
18009                    updateCurrentProfileIdsLocked();
18010                    mWindowManager.setCurrentUser(userId, mCurrentProfileIds);
18011                    // Once the internal notion of the active user has switched, we lock the device
18012                    // with the option to show the user switcher on the keyguard.
18013                    mWindowManager.lockNow(null);
18014                } else {
18015                    final Integer currentUserIdInt = Integer.valueOf(mCurrentUserId);
18016                    updateCurrentProfileIdsLocked();
18017                    mWindowManager.setCurrentProfileIds(mCurrentProfileIds);
18018                    mUserLru.remove(currentUserIdInt);
18019                    mUserLru.add(currentUserIdInt);
18020                }
18021
18022                final UserStartedState uss = mStartedUsers.get(userId);
18023
18024                // Make sure user is in the started state.  If it is currently
18025                // stopping, we need to knock that off.
18026                if (uss.mState == UserStartedState.STATE_STOPPING) {
18027                    // If we are stopping, we haven't sent ACTION_SHUTDOWN,
18028                    // so we can just fairly silently bring the user back from
18029                    // the almost-dead.
18030                    uss.mState = UserStartedState.STATE_RUNNING;
18031                    updateStartedUserArrayLocked();
18032                    needStart = true;
18033                } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
18034                    // This means ACTION_SHUTDOWN has been sent, so we will
18035                    // need to treat this as a new boot of the user.
18036                    uss.mState = UserStartedState.STATE_BOOTING;
18037                    updateStartedUserArrayLocked();
18038                    needStart = true;
18039                }
18040
18041                if (uss.mState == UserStartedState.STATE_BOOTING) {
18042                    // Booting up a new user, need to tell system services about it.
18043                    // Note that this is on the same handler as scheduling of broadcasts,
18044                    // which is important because it needs to go first.
18045                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_START_MSG, userId, 0));
18046                }
18047
18048                if (foreground) {
18049                    mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_CURRENT_MSG, userId,
18050                            oldUserId));
18051                    mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
18052                    mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18053                    mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
18054                            oldUserId, userId, uss));
18055                    mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
18056                            oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
18057                }
18058
18059                if (needStart) {
18060                    // Send USER_STARTED broadcast
18061                    Intent intent = new Intent(Intent.ACTION_USER_STARTED);
18062                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18063                            | Intent.FLAG_RECEIVER_FOREGROUND);
18064                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18065                    broadcastIntentLocked(null, null, intent,
18066                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18067                            false, false, MY_PID, Process.SYSTEM_UID, userId);
18068                }
18069
18070                if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
18071                    if (userId != UserHandle.USER_OWNER) {
18072                        Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
18073                        intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18074                        broadcastIntentLocked(null, null, intent, null,
18075                                new IIntentReceiver.Stub() {
18076                                    public void performReceive(Intent intent, int resultCode,
18077                                            String data, Bundle extras, boolean ordered,
18078                                            boolean sticky, int sendingUser) {
18079                                        onUserInitialized(uss, foreground, oldUserId, userId);
18080                                    }
18081                                }, 0, null, null, null, AppOpsManager.OP_NONE,
18082                                true, false, MY_PID, Process.SYSTEM_UID,
18083                                userId);
18084                        uss.initializing = true;
18085                    } else {
18086                        getUserManagerLocked().makeInitialized(userInfo.id);
18087                    }
18088                }
18089
18090                if (foreground) {
18091                    if (!uss.initializing) {
18092                        moveUserToForeground(uss, oldUserId, userId);
18093                    }
18094                } else {
18095                    mStackSupervisor.startBackgroundUserLocked(userId, uss);
18096                }
18097
18098                if (needStart) {
18099                    Intent intent = new Intent(Intent.ACTION_USER_STARTING);
18100                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18101                    intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18102                    broadcastIntentLocked(null, null, intent,
18103                            null, new IIntentReceiver.Stub() {
18104                                @Override
18105                                public void performReceive(Intent intent, int resultCode, String data,
18106                                        Bundle extras, boolean ordered, boolean sticky, int sendingUser)
18107                                        throws RemoteException {
18108                                }
18109                            }, 0, null, null,
18110                            INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18111                            true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18112                }
18113            }
18114        } finally {
18115            Binder.restoreCallingIdentity(ident);
18116        }
18117
18118        return true;
18119    }
18120
18121    void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
18122        long ident = Binder.clearCallingIdentity();
18123        try {
18124            Intent intent;
18125            if (oldUserId >= 0) {
18126                // Send USER_BACKGROUND broadcast to all profiles of the outgoing user
18127                List<UserInfo> profiles = mUserManager.getProfiles(oldUserId, false);
18128                int count = profiles.size();
18129                for (int i = 0; i < count; i++) {
18130                    int profileUserId = profiles.get(i).id;
18131                    intent = new Intent(Intent.ACTION_USER_BACKGROUND);
18132                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18133                            | Intent.FLAG_RECEIVER_FOREGROUND);
18134                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18135                    broadcastIntentLocked(null, null, intent,
18136                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18137                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18138                }
18139            }
18140            if (newUserId >= 0) {
18141                // Send USER_FOREGROUND broadcast to all profiles of the incoming user
18142                List<UserInfo> profiles = mUserManager.getProfiles(newUserId, false);
18143                int count = profiles.size();
18144                for (int i = 0; i < count; i++) {
18145                    int profileUserId = profiles.get(i).id;
18146                    intent = new Intent(Intent.ACTION_USER_FOREGROUND);
18147                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18148                            | Intent.FLAG_RECEIVER_FOREGROUND);
18149                    intent.putExtra(Intent.EXTRA_USER_HANDLE, profileUserId);
18150                    broadcastIntentLocked(null, null, intent,
18151                            null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18152                            false, false, MY_PID, Process.SYSTEM_UID, profileUserId);
18153                }
18154                intent = new Intent(Intent.ACTION_USER_SWITCHED);
18155                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18156                        | Intent.FLAG_RECEIVER_FOREGROUND);
18157                intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
18158                broadcastIntentLocked(null, null, intent,
18159                        null, null, 0, null, null,
18160                        android.Manifest.permission.MANAGE_USERS, AppOpsManager.OP_NONE,
18161                        false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18162            }
18163        } finally {
18164            Binder.restoreCallingIdentity(ident);
18165        }
18166    }
18167
18168    void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
18169            final int newUserId) {
18170        final int N = mUserSwitchObservers.beginBroadcast();
18171        if (N > 0) {
18172            final IRemoteCallback callback = new IRemoteCallback.Stub() {
18173                int mCount = 0;
18174                @Override
18175                public void sendResult(Bundle data) throws RemoteException {
18176                    synchronized (ActivityManagerService.this) {
18177                        if (mCurUserSwitchCallback == this) {
18178                            mCount++;
18179                            if (mCount == N) {
18180                                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18181                            }
18182                        }
18183                    }
18184                }
18185            };
18186            synchronized (this) {
18187                uss.switching = true;
18188                mCurUserSwitchCallback = callback;
18189            }
18190            for (int i=0; i<N; i++) {
18191                try {
18192                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
18193                            newUserId, callback);
18194                } catch (RemoteException e) {
18195                }
18196            }
18197        } else {
18198            synchronized (this) {
18199                sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18200            }
18201        }
18202        mUserSwitchObservers.finishBroadcast();
18203    }
18204
18205    void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18206        synchronized (this) {
18207            Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
18208            sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
18209        }
18210    }
18211
18212    void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
18213        mCurUserSwitchCallback = null;
18214        mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
18215        mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
18216                oldUserId, newUserId, uss));
18217    }
18218
18219    void onUserInitialized(UserStartedState uss, boolean foreground, int oldUserId, int newUserId) {
18220        synchronized (this) {
18221            if (foreground) {
18222                moveUserToForeground(uss, oldUserId, newUserId);
18223            }
18224        }
18225
18226        completeSwitchAndInitalize(uss, newUserId, true, false);
18227    }
18228
18229    void moveUserToForeground(UserStartedState uss, int oldUserId, int newUserId) {
18230        boolean homeInFront = mStackSupervisor.switchUserLocked(newUserId, uss);
18231        if (homeInFront) {
18232            startHomeActivityLocked(newUserId);
18233        } else {
18234            mStackSupervisor.resumeTopActivitiesLocked();
18235        }
18236        EventLogTags.writeAmSwitchUser(newUserId);
18237        getUserManagerLocked().userForeground(newUserId);
18238        sendUserSwitchBroadcastsLocked(oldUserId, newUserId);
18239    }
18240
18241    void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
18242        completeSwitchAndInitalize(uss, newUserId, false, true);
18243    }
18244
18245    void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
18246            boolean clearInitializing, boolean clearSwitching) {
18247        boolean unfrozen = false;
18248        synchronized (this) {
18249            if (clearInitializing) {
18250                uss.initializing = false;
18251                getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
18252            }
18253            if (clearSwitching) {
18254                uss.switching = false;
18255            }
18256            if (!uss.switching && !uss.initializing) {
18257                mWindowManager.stopFreezingScreen();
18258                unfrozen = true;
18259            }
18260        }
18261        if (unfrozen) {
18262            final int N = mUserSwitchObservers.beginBroadcast();
18263            for (int i=0; i<N; i++) {
18264                try {
18265                    mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
18266                } catch (RemoteException e) {
18267                }
18268            }
18269            mUserSwitchObservers.finishBroadcast();
18270        }
18271    }
18272
18273    void scheduleStartProfilesLocked() {
18274        if (!mHandler.hasMessages(START_PROFILES_MSG)) {
18275            mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
18276                    DateUtils.SECOND_IN_MILLIS);
18277        }
18278    }
18279
18280    void startProfilesLocked() {
18281        if (DEBUG_MU) Slog.i(TAG_MU, "startProfilesLocked");
18282        List<UserInfo> profiles = getUserManagerLocked().getProfiles(
18283                mCurrentUserId, false /* enabledOnly */);
18284        List<UserInfo> toStart = new ArrayList<UserInfo>(profiles.size());
18285        for (UserInfo user : profiles) {
18286            if ((user.flags & UserInfo.FLAG_INITIALIZED) == UserInfo.FLAG_INITIALIZED
18287                    && user.id != mCurrentUserId) {
18288                toStart.add(user);
18289            }
18290        }
18291        final int n = toStart.size();
18292        int i = 0;
18293        for (; i < n && i < (MAX_RUNNING_USERS - 1); ++i) {
18294            startUserInBackground(toStart.get(i).id);
18295        }
18296        if (i < n) {
18297            Slog.w(TAG_MU, "More profiles than MAX_RUNNING_USERS");
18298        }
18299    }
18300
18301    void finishUserBoot(UserStartedState uss) {
18302        synchronized (this) {
18303            if (uss.mState == UserStartedState.STATE_BOOTING
18304                    && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
18305                uss.mState = UserStartedState.STATE_RUNNING;
18306                final int userId = uss.mHandle.getIdentifier();
18307                Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
18308                intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18309                intent.addFlags(Intent.FLAG_RECEIVER_NO_ABORT);
18310                broadcastIntentLocked(null, null, intent,
18311                        null, null, 0, null, null,
18312                        android.Manifest.permission.RECEIVE_BOOT_COMPLETED, AppOpsManager.OP_NONE,
18313                        true, false, MY_PID, Process.SYSTEM_UID, userId);
18314            }
18315        }
18316    }
18317
18318    void finishUserSwitch(UserStartedState uss) {
18319        synchronized (this) {
18320            finishUserBoot(uss);
18321
18322            startProfilesLocked();
18323
18324            int num = mUserLru.size();
18325            int i = 0;
18326            while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
18327                Integer oldUserId = mUserLru.get(i);
18328                UserStartedState oldUss = mStartedUsers.get(oldUserId);
18329                if (oldUss == null) {
18330                    // Shouldn't happen, but be sane if it does.
18331                    mUserLru.remove(i);
18332                    num--;
18333                    continue;
18334                }
18335                if (oldUss.mState == UserStartedState.STATE_STOPPING
18336                        || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
18337                    // This user is already stopping, doesn't count.
18338                    num--;
18339                    i++;
18340                    continue;
18341                }
18342                if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
18343                    // Owner and current can't be stopped, but count as running.
18344                    i++;
18345                    continue;
18346                }
18347                // This is a user to be stopped.
18348                stopUserLocked(oldUserId, null);
18349                num--;
18350                i++;
18351            }
18352        }
18353    }
18354
18355    @Override
18356    public int stopUser(final int userId, final IStopUserCallback callback) {
18357        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18358                != PackageManager.PERMISSION_GRANTED) {
18359            String msg = "Permission Denial: switchUser() from pid="
18360                    + Binder.getCallingPid()
18361                    + ", uid=" + Binder.getCallingUid()
18362                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18363            Slog.w(TAG, msg);
18364            throw new SecurityException(msg);
18365        }
18366        if (userId <= 0) {
18367            throw new IllegalArgumentException("Can't stop primary user " + userId);
18368        }
18369        synchronized (this) {
18370            return stopUserLocked(userId, callback);
18371        }
18372    }
18373
18374    private int stopUserLocked(final int userId, final IStopUserCallback callback) {
18375        if (DEBUG_MU) Slog.i(TAG_MU, "stopUserLocked userId=" + userId);
18376        if (mCurrentUserId == userId) {
18377            return ActivityManager.USER_OP_IS_CURRENT;
18378        }
18379
18380        final UserStartedState uss = mStartedUsers.get(userId);
18381        if (uss == null) {
18382            // User is not started, nothing to do...  but we do need to
18383            // callback if requested.
18384            if (callback != null) {
18385                mHandler.post(new Runnable() {
18386                    @Override
18387                    public void run() {
18388                        try {
18389                            callback.userStopped(userId);
18390                        } catch (RemoteException e) {
18391                        }
18392                    }
18393                });
18394            }
18395            return ActivityManager.USER_OP_SUCCESS;
18396        }
18397
18398        if (callback != null) {
18399            uss.mStopCallbacks.add(callback);
18400        }
18401
18402        if (uss.mState != UserStartedState.STATE_STOPPING
18403                && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18404            uss.mState = UserStartedState.STATE_STOPPING;
18405            updateStartedUserArrayLocked();
18406
18407            long ident = Binder.clearCallingIdentity();
18408            try {
18409                // We are going to broadcast ACTION_USER_STOPPING and then
18410                // once that is done send a final ACTION_SHUTDOWN and then
18411                // stop the user.
18412                final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
18413                stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18414                stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
18415                stoppingIntent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
18416                final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
18417                // This is the result receiver for the final shutdown broadcast.
18418                final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
18419                    @Override
18420                    public void performReceive(Intent intent, int resultCode, String data,
18421                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18422                        finishUserStop(uss);
18423                    }
18424                };
18425                // This is the result receiver for the initial stopping broadcast.
18426                final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
18427                    @Override
18428                    public void performReceive(Intent intent, int resultCode, String data,
18429                            Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
18430                        // On to the next.
18431                        synchronized (ActivityManagerService.this) {
18432                            if (uss.mState != UserStartedState.STATE_STOPPING) {
18433                                // Whoops, we are being started back up.  Abort, abort!
18434                                return;
18435                            }
18436                            uss.mState = UserStartedState.STATE_SHUTDOWN;
18437                        }
18438                        mBatteryStatsService.noteEvent(
18439                                BatteryStats.HistoryItem.EVENT_USER_RUNNING_FINISH,
18440                                Integer.toString(userId), userId);
18441                        mSystemServiceManager.stopUser(userId);
18442                        broadcastIntentLocked(null, null, shutdownIntent,
18443                                null, shutdownReceiver, 0, null, null, null, AppOpsManager.OP_NONE,
18444                                true, false, MY_PID, Process.SYSTEM_UID, userId);
18445                    }
18446                };
18447                // Kick things off.
18448                broadcastIntentLocked(null, null, stoppingIntent,
18449                        null, stoppingReceiver, 0, null, null,
18450                        INTERACT_ACROSS_USERS, AppOpsManager.OP_NONE,
18451                        true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18452            } finally {
18453                Binder.restoreCallingIdentity(ident);
18454            }
18455        }
18456
18457        return ActivityManager.USER_OP_SUCCESS;
18458    }
18459
18460    void finishUserStop(UserStartedState uss) {
18461        final int userId = uss.mHandle.getIdentifier();
18462        boolean stopped;
18463        ArrayList<IStopUserCallback> callbacks;
18464        synchronized (this) {
18465            callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
18466            if (mStartedUsers.get(userId) != uss) {
18467                stopped = false;
18468            } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
18469                stopped = false;
18470            } else {
18471                stopped = true;
18472                // User can no longer run.
18473                mStartedUsers.remove(userId);
18474                mUserLru.remove(Integer.valueOf(userId));
18475                updateStartedUserArrayLocked();
18476
18477                // Clean up all state and processes associated with the user.
18478                // Kill all the processes for the user.
18479                forceStopUserLocked(userId, "finish user");
18480            }
18481
18482            // Explicitly remove the old information in mRecentTasks.
18483            removeRecentTasksForUserLocked(userId);
18484        }
18485
18486        for (int i=0; i<callbacks.size(); i++) {
18487            try {
18488                if (stopped) callbacks.get(i).userStopped(userId);
18489                else callbacks.get(i).userStopAborted(userId);
18490            } catch (RemoteException e) {
18491            }
18492        }
18493
18494        if (stopped) {
18495            mSystemServiceManager.cleanupUser(userId);
18496            synchronized (this) {
18497                mStackSupervisor.removeUserLocked(userId);
18498            }
18499        }
18500    }
18501
18502    @Override
18503    public UserInfo getCurrentUser() {
18504        if ((checkCallingPermission(INTERACT_ACROSS_USERS)
18505                != PackageManager.PERMISSION_GRANTED) && (
18506                checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18507                != PackageManager.PERMISSION_GRANTED)) {
18508            String msg = "Permission Denial: getCurrentUser() from pid="
18509                    + Binder.getCallingPid()
18510                    + ", uid=" + Binder.getCallingUid()
18511                    + " requires " + INTERACT_ACROSS_USERS;
18512            Slog.w(TAG, msg);
18513            throw new SecurityException(msg);
18514        }
18515        synchronized (this) {
18516            return getUserManagerLocked().getUserInfo(mCurrentUserId);
18517        }
18518    }
18519
18520    int getCurrentUserIdLocked() {
18521        return mCurrentUserId;
18522    }
18523
18524    @Override
18525    public boolean isUserRunning(int userId, boolean orStopped) {
18526        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18527                != PackageManager.PERMISSION_GRANTED) {
18528            String msg = "Permission Denial: isUserRunning() from pid="
18529                    + Binder.getCallingPid()
18530                    + ", uid=" + Binder.getCallingUid()
18531                    + " requires " + INTERACT_ACROSS_USERS;
18532            Slog.w(TAG, msg);
18533            throw new SecurityException(msg);
18534        }
18535        synchronized (this) {
18536            return isUserRunningLocked(userId, orStopped);
18537        }
18538    }
18539
18540    boolean isUserRunningLocked(int userId, boolean orStopped) {
18541        UserStartedState state = mStartedUsers.get(userId);
18542        if (state == null) {
18543            return false;
18544        }
18545        if (orStopped) {
18546            return true;
18547        }
18548        return state.mState != UserStartedState.STATE_STOPPING
18549                && state.mState != UserStartedState.STATE_SHUTDOWN;
18550    }
18551
18552    @Override
18553    public int[] getRunningUserIds() {
18554        if (checkCallingPermission(INTERACT_ACROSS_USERS)
18555                != PackageManager.PERMISSION_GRANTED) {
18556            String msg = "Permission Denial: isUserRunning() from pid="
18557                    + Binder.getCallingPid()
18558                    + ", uid=" + Binder.getCallingUid()
18559                    + " requires " + INTERACT_ACROSS_USERS;
18560            Slog.w(TAG, msg);
18561            throw new SecurityException(msg);
18562        }
18563        synchronized (this) {
18564            return mStartedUserArray;
18565        }
18566    }
18567
18568    private void updateStartedUserArrayLocked() {
18569        int num = 0;
18570        for (int i=0; i<mStartedUsers.size();  i++) {
18571            UserStartedState uss = mStartedUsers.valueAt(i);
18572            // This list does not include stopping users.
18573            if (uss.mState != UserStartedState.STATE_STOPPING
18574                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18575                num++;
18576            }
18577        }
18578        mStartedUserArray = new int[num];
18579        num = 0;
18580        for (int i=0; i<mStartedUsers.size();  i++) {
18581            UserStartedState uss = mStartedUsers.valueAt(i);
18582            if (uss.mState != UserStartedState.STATE_STOPPING
18583                    && uss.mState != UserStartedState.STATE_SHUTDOWN) {
18584                mStartedUserArray[num] = mStartedUsers.keyAt(i);
18585                num++;
18586            }
18587        }
18588    }
18589
18590    @Override
18591    public void registerUserSwitchObserver(IUserSwitchObserver observer) {
18592        if (checkCallingPermission(INTERACT_ACROSS_USERS_FULL)
18593                != PackageManager.PERMISSION_GRANTED) {
18594            String msg = "Permission Denial: registerUserSwitchObserver() from pid="
18595                    + Binder.getCallingPid()
18596                    + ", uid=" + Binder.getCallingUid()
18597                    + " requires " + INTERACT_ACROSS_USERS_FULL;
18598            Slog.w(TAG, msg);
18599            throw new SecurityException(msg);
18600        }
18601
18602        mUserSwitchObservers.register(observer);
18603    }
18604
18605    @Override
18606    public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
18607        mUserSwitchObservers.unregister(observer);
18608    }
18609
18610    private boolean userExists(int userId) {
18611        if (userId == 0) {
18612            return true;
18613        }
18614        UserManagerService ums = getUserManagerLocked();
18615        return ums != null ? (ums.getUserInfo(userId) != null) : false;
18616    }
18617
18618    int[] getUsersLocked() {
18619        UserManagerService ums = getUserManagerLocked();
18620        return ums != null ? ums.getUserIds() : new int[] { 0 };
18621    }
18622
18623    UserManagerService getUserManagerLocked() {
18624        if (mUserManager == null) {
18625            IBinder b = ServiceManager.getService(Context.USER_SERVICE);
18626            mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
18627        }
18628        return mUserManager;
18629    }
18630
18631    private int applyUserId(int uid, int userId) {
18632        return UserHandle.getUid(userId, uid);
18633    }
18634
18635    ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
18636        if (info == null) return null;
18637        ApplicationInfo newInfo = new ApplicationInfo(info);
18638        newInfo.uid = applyUserId(info.uid, userId);
18639        newInfo.dataDir = USER_DATA_DIR + userId + "/"
18640                + info.packageName;
18641        return newInfo;
18642    }
18643
18644    ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
18645        if (aInfo == null
18646                || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
18647            return aInfo;
18648        }
18649
18650        ActivityInfo info = new ActivityInfo(aInfo);
18651        info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
18652        return info;
18653    }
18654
18655    private final class LocalService extends ActivityManagerInternal {
18656        @Override
18657        public void goingToSleep() {
18658            ActivityManagerService.this.goingToSleep();
18659        }
18660
18661        @Override
18662        public void wakingUp() {
18663            ActivityManagerService.this.wakingUp();
18664        }
18665
18666        @Override
18667        public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
18668                String processName, String abiOverride, int uid, Runnable crashHandler) {
18669            return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
18670                    processName, abiOverride, uid, crashHandler);
18671        }
18672    }
18673
18674    /**
18675     * An implementation of IAppTask, that allows an app to manage its own tasks via
18676     * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
18677     * only the process that calls getAppTasks() can call the AppTask methods.
18678     */
18679    class AppTaskImpl extends IAppTask.Stub {
18680        private int mTaskId;
18681        private int mCallingUid;
18682
18683        public AppTaskImpl(int taskId, int callingUid) {
18684            mTaskId = taskId;
18685            mCallingUid = callingUid;
18686        }
18687
18688        private void checkCaller() {
18689            if (mCallingUid != Binder.getCallingUid()) {
18690                throw new SecurityException("Caller " + mCallingUid
18691                        + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
18692            }
18693        }
18694
18695        @Override
18696        public void finishAndRemoveTask() {
18697            checkCaller();
18698
18699            synchronized (ActivityManagerService.this) {
18700                long origId = Binder.clearCallingIdentity();
18701                try {
18702                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18703                    if (tr == null) {
18704                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18705                    }
18706                    // Only kill the process if we are not a new document
18707                    int flags = tr.getBaseIntent().getFlags();
18708                    boolean isDocument = (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) ==
18709                            Intent.FLAG_ACTIVITY_NEW_DOCUMENT;
18710                    removeTaskByIdLocked(mTaskId,
18711                            !isDocument ? ActivityManager.REMOVE_TASK_KILL_PROCESS : 0);
18712                } finally {
18713                    Binder.restoreCallingIdentity(origId);
18714                }
18715            }
18716        }
18717
18718        @Override
18719        public ActivityManager.RecentTaskInfo getTaskInfo() {
18720            checkCaller();
18721
18722            synchronized (ActivityManagerService.this) {
18723                long origId = Binder.clearCallingIdentity();
18724                try {
18725                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18726                    if (tr == null) {
18727                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18728                    }
18729                    return createRecentTaskInfoFromTaskRecord(tr);
18730                } finally {
18731                    Binder.restoreCallingIdentity(origId);
18732                }
18733            }
18734        }
18735
18736        @Override
18737        public void moveToFront() {
18738            checkCaller();
18739
18740            final TaskRecord tr;
18741            synchronized (ActivityManagerService.this) {
18742                tr = recentTaskForIdLocked(mTaskId);
18743                if (tr == null) {
18744                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18745                }
18746                if (tr.getRootActivity() != null) {
18747                    long origId = Binder.clearCallingIdentity();
18748                    try {
18749                        moveTaskToFrontLocked(tr.taskId, 0, null);
18750                        return;
18751                    } finally {
18752                        Binder.restoreCallingIdentity(origId);
18753                    }
18754                }
18755            }
18756
18757            startActivityFromRecentsInner(tr.taskId, null);
18758        }
18759
18760        @Override
18761        public int startActivity(IBinder whoThread, String callingPackage,
18762                Intent intent, String resolvedType, Bundle options) {
18763            checkCaller();
18764
18765            int callingUser = UserHandle.getCallingUserId();
18766            TaskRecord tr;
18767            IApplicationThread appThread;
18768            synchronized (ActivityManagerService.this) {
18769                tr = recentTaskForIdLocked(mTaskId);
18770                if (tr == null) {
18771                    throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18772                }
18773                appThread = ApplicationThreadNative.asInterface(whoThread);
18774                if (appThread == null) {
18775                    throw new IllegalArgumentException("Bad app thread " + appThread);
18776                }
18777            }
18778            return mStackSupervisor.startActivityMayWait(appThread, -1, callingPackage, intent,
18779                    resolvedType, null, null, null, null, 0, 0, null, null,
18780                    null, options, callingUser, null, tr);
18781        }
18782
18783        @Override
18784        public void setExcludeFromRecents(boolean exclude) {
18785            checkCaller();
18786
18787            synchronized (ActivityManagerService.this) {
18788                long origId = Binder.clearCallingIdentity();
18789                try {
18790                    TaskRecord tr = recentTaskForIdLocked(mTaskId);
18791                    if (tr == null) {
18792                        throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
18793                    }
18794                    Intent intent = tr.getBaseIntent();
18795                    if (exclude) {
18796                        intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18797                    } else {
18798                        intent.setFlags(intent.getFlags()
18799                                & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
18800                    }
18801                } finally {
18802                    Binder.restoreCallingIdentity(origId);
18803                }
18804            }
18805        }
18806    }
18807}
18808